Using Kill Bill APIs
Introduction
Kill Bill offers a set of HTTP APIs, commonly called REST APIs, that use the HTTP verbs POST
, GET
, PUT
, DELETE
to invoke Create, Read, Update and Delete (CRUD) operations, and that use HTTP response codes to indicate errors. These APIs enable the management of Kill Bill resources -- e.g Account
-- through the use of JSON input and output.
Kill Bill also offers a set of java APIs that can be used by plugins to make requests, and a set of java plugin APIs for Kill Bill core to interact with the plugins. These apis are beyond the scope of this documentation.
API client libraries
Official libraries for the Kill Bill API are available in several languages, including Java, Php, Python, Ruby, Node, and Go. Community-supported libraries such as .NET are also available. Note that code examples for Curl, Java, Ruby and Python are shown in the right-hand column of this document.
In the following documentation, we assume
you have a Kill Bill server instance running on 127.0.0.1
on port 8080
. It is straightforward to substitute a different IP address or port number if necessary.
Kill Bill supports the https
protocol, but here all examples are shown using http
.
//
// You can find the java client on github: https://github.com/killbill/killbill-client-java
//
#
# You can find the ruby client on github: https://github.com/killbill/killbill-client-ruby
#
The description of the API in this documentation is limited to the most common use cases and does not include advanced features that we have crafted over the years from all the use cases we have seen from our users.
For questions about API use, or to report bugs, you can subscribe to the Kill Bill user mailing list.
Authentication and RBAC
In order to make API calls, one needs to authenticate each request by passing an HTTP Authorization
header and by following the HTTP Basic authentication scheme.
Depending on how the system has been configured, the authentication mechanism can happen using different options -- some or all at the same time:
- Flat file configuration
- Database configuration
- LDAP configuration
- OKTA configuration
The system also supports configuring roles and permissions, to restrict user access to certain resources and operations. The permissions are quite granular and are defined here
Multi-Tenancy
Kill Bill has been designed from the ground up to run multiple logical instances on the same set of servers and databases. This allows different customer data sets to be cleanly separated. Another common use case is to configure both a production tenant and a test tenant, the latter being used for test requests during deployment and for sanity after deployment.
Each API call requires the tenant being used to be identified, through the use of 2 HTTP headers:
X-Killbill-ApiKey
: The API key associated with the tenant. This value is stored in clear in the database.X-Killbill-ApiSecret
: The API secret associated with the tenant. This value is hashed and stored along with thesalt
in the database
Specifying the basic authentication headers and multi-tenancy headers:
curl \
-u admin:password \
-H "X-Killbill-ApiKey: bob" \
-H "X-Killbill-ApiSecret: lazar" \
...
KillBillHttpClient killBillHttpClient = new KillBillHttpClient(String.format("http://%s:%d", "127.0.0.1", 8080),
username,
password,
apiKey,
apiSecret,
null,
null,
1000,
5000,
5000);
AccountApi accountApi = new AccountApi(killBillHttpClient);
AdminApi adminApi = new AdminApi(killBillHttpClient);
BundleApi bundleApi = new BundleApi(killBillHttpClient);
CatalogApi catalogApi = new CatalogApi(killBillHttpClient);
CreditApi creditApi = new CreditApi(killBillHttpClient);
CustomFieldApi customFieldApi = new CustomFieldApi(killBillHttpClient);
ExportApi exportApi = new ExportApi(killBillHttpClient);
InvoiceApi invoiceApi = new InvoiceApi(killBillHttpClient);
InvoiceItemApi invoiceItemApi = new InvoiceItemApi(killBillHttpClient);
InvoicePaymentApi invoicePaymentApi = new InvoicePaymentApi(killBillHttpClient);
NodesInfoApi nodesInfoApi = new NodesInfoApi(killBillHttpClient);
OverdueApi overdueApi = new OverdueApi(killBillHttpClient);
PaymentApi paymentApi = new PaymentApi(killBillHttpClient);
PaymentGatewayApi paymentGatewayApi = new PaymentGatewayApi(killBillHttpClient);
PaymentMethodApi paymentMethodApi = new PaymentMethodApi(killBillHttpClient);
PaymentTransactionApi paymentTransactionApi = new PaymentTransactionApi(killBillHttpClient);
PluginInfoApi pluginInfoApi = new PluginInfoApi(killBillHttpClient);
SecurityApi securityApi = new SecurityApi(killBillHttpClient);
SubscriptionApi subscriptionApi = new SubscriptionApi(killBillHttpClient);
TagApi tagApi = new TagApi(killBillHttpClient);
TagDefinitionApi tagDefinitionApi = new TagDefinitionApi(killBillHttpClient);
TenantApi tenantApi = new TenantApi(killBillHttpClient);
UsageApi usageApi = new UsageApi(killBillHttpClient);
// Request Options example
String createdBy = "me";
String reason = "Going through my first tutorial";
String comment = "I like it!";
String apiKey = "bob";
String apiSecret = "lazar";
RequestOptions requestOptions = RequestOptions.builder()
.withCreatedBy(createdBy)
.withReason(reason)
.withComment(comment)
.withQueryParams(queryParams)
.withTenantApiKey(apiKey)
.withTenantApiSecret(apiSecret)
.build();
require 'killbill_client'
KillBillClient.url = 'http://127.0.0.1:8080'
# Multi-tenancy and RBAC credentials
options = {
:username => 'admin',
:password => 'password',
:api_key => 'bob',
:api_secret => 'lazar'
}
# Audit log data
user = 'me'
reason = 'Going through my first tutorial'
comment = 'I like it!'
# Start using....
# Edit file: configuration.py, lines:50-62
# Default Base url
self.host = "http://localhost:8080"
# Temp file folder for downloading files
self.temp_folder_path = None
# Authentication Settings
# dict to store API key(s)
self.api_key = {}
# dict to store API prefix (e.g. Bearer)
self.api_key_prefix = {}
# Username for HTTP basic authentication
self.username = "admin"
# Password for HTTP basic authentication
self.password = "password"
####################################################
# Basic example using the client
exampleApi = killbill.api.ExampleApi()
body = Example(name='John', last_name = 'Doe')
created_by = 'me'
api_key = 'bob'
api_secret = 'lazar'
exampleApi.create(body,
created_by,
api_key,
api_secret)
Resource IDs and External Keys
When a new resource is created, there are 2 IDS associated with it. Kill Bill will allocate a unique ID, and the user of the API will also be able to associate its own unique key, called the external key
. The external key is used for 2 scenarios:
- ID Mapping: Typically an external key can be passed to create a mapping between the ID generated by Kill Bill and a known key for this resource
- Idempotency: Kill Bill ensures that each external key is unique, so if an API call times out, it can be safely retried with the same external key. The second request would only succeed if the first one did not complete. This ensures idempotency of the call, since the external key is unique per tenant and across all resources.
Pagination
Besides the traditional CRUD APIs associated with each resource, we also offer pagination APIs to allow the listing of per-tenant resources, such as all Account
s for a given tenant. These APIs include an offset
and a limit
, provided as query parameters, to allow the listing of all resources of a given type, on a page by page basis. In addition to the json list, each response will also include the following http headers:
X-Killbill-Pagination-CurrentOffset
: The offest of the first record in the returned listX-Killbill-Pagination-NextOffset
: The header will only be present if there are additional entries to return and would include the next offsetX-Killbill-Pagination-TotalNbRecords
: The total number of recordsX-Killbill-Pagination-NextPageUri
: The uri that can be used to retrieve the next page.
Audit and History
Every api in Kill Bill that creates, or modifies state will create an audit log record to track who made the change. In addition, we also allow the record to specify why this change was made. This information is passed for every POST
, PUT
, and DELETE
request and relies on special HTTP headers:
X-Killbill-CreatedBy
: Mandatory header to track who made the change.X-Killbill-Reason
: Optional header to track the reason; typically one would use a special reason code -- e.g COURTESY_REFUND.X-Killbill-Comment
: Optional header to track the metadata; typically one would add more information -- e.g 'Good old faithful customer'.
In addition to the audit log, Kill Bill also records the history of the changes. For instance updating the billing addess of a customer would create an additonal row to track the change and link it to the audit log. The audit
query parameter can take the following values:
NONE
[Default]: No audit log is beeing returned.MINIMAL
: Only rows associated to inserts are being returned, but noupdates
.FULL
: Everything is being returned.
Request: Fetching an account specifying
audit=MINIMAL
curl \
-u admin:password \
-H "X-Killbill-ApiKey: bob" \
-H "X-Killbill-ApiSecret: lazar" \
-H "Content-Type: application/json" \
-H "X-Killbill-CreatedBy: demo" \
"http://127.0.0.1:8080/1.0/kb/accounts/e8877928-0226-488d-9272-07a5e66d897f?audit=MINIMAL"
Account result = accountApi.getAccount(accountId,
false,
false,
AuditLevel.MINIMAL,
requestOptions);
TODO Api does not exist ;-(
Response:
{
...
"auditLogs": [
{
"changeType": "INSERT",
"changeDate": "2018-02-05T22:39:53.000Z",
"changedBy": "demo",
"reasonCode": null,
"comments": null,
"userToken": "4858a67e-03b0-4d94-8a8c-bcd6e8599452"
}
]
}
Every API that retrieves information, whether associated with a specific resource, or with a list of resources, may return audit logs.
Audit and history information associated with a given resource is always stored atomically to ensure that if the state is changed, such audit and history information exists and is accurate.
Versioning
Kill Bill Server
Kill Bill software is composed of many different repositories, all of them hosted on our github account.
The Kill Bill server version, or simply Kill Bill version, is the one from the killbill repository, and more specifically since we are using maven
to build, this is indicated in the corresponding pom.xml
. This repository depends on a few others, each having their own versions:
killbill-api
: APIs used by plugins to communicate with Kill Bill corekillbill-plugin-api
: APIs used by Kill Bill core to communicate with pluginskillbill-commons
: Common code across moduleskillbill-platform
: Platform related code such as OSGI framework, webapp pieceskillbill-client
: Java client, only used for integration tests inside killbill repository.
The version for all these dependencies is managed in the parent pom.xml. So in particular, for a given Kill Bill version, you can look up the version of the parent pom.xml
and from there access all the dependencies.
The current stable and production ready version of Kill Bill is 0.24.y
. You should use the latest released (y
) version as it may contain critical bug fixes.
- Any bug fixes will result in a new version identified by incrementing the
patch
number (y
). We guarantee compatibility of these versions with those immediately preceding them. Each version will be accompanied by release notes on github - e.g 0.22.8 release notes. - New development may happen in parallel. This may lead to the release of development versions. Such versions are not yet deemed stable, and will not be supported on the public mailing list.
The choice of releasing 0.x.y
and not 1.x.y
is motivated by our desire to add additional features in upcoming releases, and is in no way a statement about code instability.
Client Libraries
Our client libraries contain a README
section to describe their compatibility with the Kill Bill server. For instance, such compatibility mapping can be seen in our java client here.
Plugins
Each plugin also has its own version, and we also keep a README
with the mapping section. For example, such a section for the adyen payment plugin can be found here.
We also keep a global repository for all plugins here. The simple file-based approach is an internal implementation. This brings us to our next topic, KPM
.
KPM
KPM
, The Kill Bill Package Manager, provides among other things the ability to retrieve version mapping for dependencies and plugins -- see the example on the right side.
# Look up version dependencies matching Kill Bill release 0.22.8:
> kpm info --version=0.22.8
Fetching info for version 0.22.8...
Dependencies for version 0.22.8
killbill 0.22.8
killbill-oss-parent 0.143.60
killbill-api 0.53.17
killbill-plugin-api 0.26.4
killbill-commons 0.23.11
killbill-platform 0.39.15
Known plugins for KB version 0.22.8
analytics 7.0.8
avatax 0.7.0
email-notifications 0.6.1
payment-test 7.0.4
stripe 7.0.4
...
Errors
Kill Bill relies on HTTP response codes to indicate the success or failure of an API request:
2xx
status indicates success4xx
status often indicates a client side error -- e.g missing madatory API field5xx
status indicates an error with Kill Bill's servers or third party system -- e.g payment gateway returns 5xx.
HTTP status code summary:
200 - OK: A response body may be returned.
201 - Created: Success in creating a new resource. A Location header is returned to indicate the uri that can be used to fetch the resource
202 - Accepted: The request has been accepted and will be processed asynchronously.
204 - No Content: The request was processed sucesfully but no response body is returned.
400 - Bad Request: Invalid/missing parameter from client.
401 - Unauthorized: Authorization failed.
402 - Request Failed: Request parameter were valid but request failed -- insufficient fund on a payment request.
404 - Not Found: The requested resource does not exist.
409 - Conflict: The request conflicts with another request.
422 - Unprocessable Entity: Payment control plugin aborted the call.
500 - Unexpected system error.
502 - Bad Gateway : Unknow failure from payment plugin (PLUGIN_FAILURE).
503 - Service Unavailable: Kill Bill or a third party system -- e.g payment gateway -- is unavailable.
504 - Gateway Timeout: Payment gateway timed out.
In addition to these error codes, the system will often return some json to provide more details about the error:
code
: Each error in Kill Bill is associated with a an ErrorCode.formattedMsg
: A description of the error for the specific resource(s).cause
: An optional stack trace.
Additional Resources
Our main documentation is found here.
Tenant
Tenant Resource
Kill Bill has been designed from the ground up as a multi-tenant system, that is, one where multiple unrelated deployments can be hosted on the same physical system. Each deployment has its own separate configuration, catalog, and plugins, and of course its data set is kept entirely separate from the others. RBAC control allows different users/admin/apps to access zero, one or multiple tenants. This blog illustrates some interesting use cases. The Tenant
resource allows the management of such tenants.
The attributes of the Tenant
resource object are the following:
Name | Type | Generated by | Description |
---|---|---|---|
tenantId | string | system | UUID for this tenant |
externalKey | string | system or user | Optional external key provided by the client |
apiKey | string | user | The API key associated with the tenant |
apiSecret | string | user | The API secret associated with the tenant. This value is hashed and cannot be retrieved. |
auditLogs | array | system | Array of audit log records for this tenant |
Note that the tenant itself has very few attributes, as most attributes belong to the individual accounts and related resources.
Tenant
These endpoints manage information that is maintained at the tenant level. Unless otherwise stated, the tenant is identified by its API key in the header.
Create a tenant
This API creates a new tenant.
Note: If you create a tenant using this API, it will not be recognized immediately by KAUI because KAUI will be unable to retrieve the apiSecret
. To fix this, you should "create" the same tenant separately after logging into KAUI. This will not create another tenant, but it will synchronize KAUI with the one already created.
HTTP Request
POST http://127.0.0.1:8080/1.0/kb/tenants
Example Request:
curl -v \
-X POST \
-u admin:password \
-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 '{ "apiKey": "bob", "apiSecret": "lazar"}' \
"http://127.0.0.1:8080/1.0/kb/tenants"
import org.killbill.billing.client.api.gen.TenantApi;
protected TenantApi tenantApi;
UUID tenantId = null;
String externalKey = null;
String apiKey = "bob";
String apiSecret = "lazar";
List<AuditLog> EMPTY_AUDIT_LOGS = Collections.emptyList();
Tenant body = new Tenant(tenantId,
externalKey,
apiKey,
apiSecret,
EMPTY_AUDIT_LOGS);
tenantApi.createTenant(body, requestOptions);
tenant = KillBillClient::Model::Tenant.new
tenant.external_key = "demo_external_key"
tenant.api_key = "demo_api_key"
tenant.api_secret = "demo_api_secret"
use_global_defalut = true
user = "demo"
reason = nil
comment = nil
tenant.create(use_global_defalut,
user,
reason,
comment,
options)
tenantApi = killbill.api.TenantApi()
body = Tenant(api_key='demo_api_key', api_secret='demo_api_secret')
tenantApi.create_tenant(body, created_by='demo')
Example Response:
# Subset of headers returned when specifying -v curl option
< HTTP/1.1 201 Created
< Location: http://localhost:8080/1.0/kb/tenants/e7b03c81-f41a-4eb7-a645-b9166057f186
< Content-Type: application/json
< Content-Length: 0
class Tenant {
tenantId: 5cce926f-7f3a-4007-a5a0-e5b55fc50079
externalKey: null
apiKey: bob
apiSecret: lazar
auditLogs: []
}
{
"tenantId":"ab5981c2-de14-43d6-a35b-a2ed0b28c746",
"externalKey":"demo_external_key",
"apiKey":"bob"
}
no content
Request Body
A JSON string representing a Tenant resource. The only parameters required are apiKey
and apiSecret
. The externalKey
is optional and will be set to null if not supplied. The tenantId
is generated by the system.
Query Parameters
Name | Type | Required | Default | Description |
---|---|---|---|---|
useGlobalDefault | boolean | false | false | If true, configure the tenant with a default catalog |
Setting the useGlobalDefault
parameter to true
can be used for test purposes. This will configure the tenant with a default catalog, and therefore make it easy to quickly start playing with the apis. Note that in order to then upload a new custom catalog, one would need to invalidate the caches for this tenant.
Response
If successful, returns a status code of 201 and an empty body. In addition a Location
parameter is returned in the header. This parameter gives the URL for the tenant, including the tenantId
.
Retrieve a tenant by id
Retrieves a tenant resource, given its ID.
HTTP Request
GET http://127.0.0.1:8080/1.0/kb/tenants/{tenantId}
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/tenants/6907712e-e940-4033-8695-36894db128d3"
import org.killbill.billing.client.api.gen.TenantApi;
protected TenantApi tenantApi;
UUID tenantId = UUID.fromString("6907712e-e940-4033-8695-36894db128d3");
tenantApi.getTenant(tenantId, requestOptions);
tenant_id = "ab5981c2-de14-43d6-a35b-a2ed0b28c746"
KillBillClient::Model::Tenant.find_by_id(tenant_id, options)
tenantApi = killbill.api.TenantApi()
tenant.get_tenant(tenant_id='3d90ec45-c640-4fd7-abde-798bc582513b')
Example Response:
{
"tenantId": "6907712e-e940-4033-8695-36894db128d3",
"externalKey": "1532546166-326384",
"apiKey": "bob",
"apiSecret": null,
"auditLogs": []
}
class Tenant {
"tenantId": "6907712e-e940-4033-8695-36894db128d3",
"externalKey": "1532546166-326384",
"apiKey": "bob",
"apiSecret": null,
"auditLogs": []
}
{
"tenantId":"ab5981c2-de14-43d6-a35b-a2ed0b28c746",
"externalKey":"demo_external_key",
"apiKey":"bob"
}
{'api_key': 'udwg',
'api_secret': None,
'audit_logs': [],
'external_key': None,
'tenant_id': '3d90ec45-c640-4fd7-abde-798bc582513b'}
Query Parameters
none
Response
If successful, returns a status code of 200 and a tenant resource object. The apiSecret
attribute is returned as null
, since it cannot be retrieved.
Retrieve a tenant by its API key
Retrieves a tenant resource, given its apiKey
. The apiKey
is passed as a query parameter.
HTTP Request
GET http://127.0.0.1:8080/1.0/kb/tenants
Example Request:
curl -v \
-u admin:password \
-H "Accept: application/json" \
"http://127.0.0.1:8080/1.0/kb/tenants?apiKey=bob"
import org.killbill.billing.client.api.gen.TenantApi;
protected TenantApi tenantApi;
String apiKey = "bob";
tenantApi.getTenantByApiKey(apiKey, requestOptions);
api_key = "demo_api_key"
KillBillClient::Model::Tenant.find_by_api_key(api_key, options)
tenantApi = killbill.api.TenantApi()
tenantApi.get_tenant_by_api_key(api_key='bob')
Example Response:
{
"tenantId": "6907712e-e940-4033-8695-36894db128d3",
"externalKey": "1532546166-326384",
"apiKey": "bob",
"apiSecret": null,
"auditLogs": []
}
{
"tenantId": "6907712e-e940-4033-8695-36894db128d3",
"externalKey": "1532546166-326384",
"apiKey": "bob",
"apiSecret": null,
"auditLogs": []
}
{
"tenantId":"ab5981c2-de14-43d6-a35b-a2ed0b28c746",
"externalKey":"demo_external_key",
"apiKey":"bob"
}
{'api_key': 'bob',
'api_secret': None,
'audit_logs': [],
'external_key': None,
'tenant_id': '3d90ec45-c640-4fd7-abde-798bc582513b'}
Query Parameters
Name | Type | Required | Default | Description |
---|---|---|---|---|
apiKey | string | true | none | api key |
Response
If successful, returns a status code of 200 and a tenant resource object. The apiSecret
attribute is returned as null
, since it cannot be retrieved.
Push Notifications
Push notifications are a convenient way to get notified about events from the system.
One can register a callback, i.e, a valid URL that will be called whenever there is an event dispatched for this tenant.
Note that this can result in a large number of calls; every time there is a state change for one of the Accounts
in this tenant, the callback will be invoked.
In case of error, the system will retry the callback as defined by the system property org.killbill.billing.server.notifications.retries
.
See push notification documentation here for further information.
Register a push notification
Register a callback URL for this tenant for push notifications.The key name is PUSH_NOTIFICATION_CB. The API sets the value of this key, replacing any previous value.
HTTP Request
POST http://127.0.0.1:8080/1.0/kb/tenants/registerNotificationCallback
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/tenants/registerNotificationCallback?cb=http://demo/callmeback'
import org.killbill.billing.client.api.gen.TenantApi;
protected TenantApi tenantApi;
String cb = "http://demo/callmeback";
TenantKeyValue result = tenantApi.registerPushNotificationCallback(cb, requestOptions);
TODO
tenantApi = killbill.api.TenantApi()
tenantApi.register_push_notification_callback(created_by='demo', cb='http://demo/callmeback')
Example Response:
# Subset of headers returned when specifying -v curl option
< HTTP/1.1 201 Created
< Location: http://localhost:8080/1.0/kb/tenants/registerNotificationCallback
< Content-Type: application/json
< Content-Length: 0
class TenantKeyValue {
key: PUSH_NOTIFICATION_CB
values: [http://demo/callmeback]
}
TODO
no content
Query Parameters
Name | Type | Required | Default | Description |
---|---|---|---|---|
cb | string | true | none | callback URL to register |
Response
If successful, returns a status code of 201 and an empty body. In addition, a Location
item is returned in the header giving the URL for this callback.
Retrieve a registered push notification
Gets the push notification registered for this tenant, if any.
HTTP Request
GET http://127.0.0.1:8080/1.0/kb/tenants/registerNotificationCallback
Example Request:
curl -v \
-u admin:password \
-H "X-Killbill-ApiKey: bob" \
-H "X-Killbill-ApiSecret: lazar" \
-H "Accept: application/json" \
"http://localhost:8080/1.0/kb/tenants/registerNotificationCallback"
import org.killbill.billing.client.api.gen.TenantApi;
protected TenantApi tenantApi;
TenantKeyValue result = tenantApi.getPushNotificationCallbacks(requestOptions);
TODO
tenantApi = killbill.api.TenantApi()
tenantApi.get_push_notification_callbacks()
Example Response:
# Subset of headers returned when specifying -v curl option
< HTTP/1.1 200 OK
< Content-Type: application/json
{
"key": "PUSH_NOTIFICATION_CB",
"values": [
"http://demo/callmeback"
]
}
class TenantKeyValue {
key: PUSH_NOTIFICATION_CB
values: [http://demo/callmeback]
}
TODO
{'key': 'PUSH_NOTIFICATION_CB', 'values': ['http://demo/callmeback']}
Query Parameters
None.
Response
If successful, returns a status code of 200 and a body containing a key-value object as follows:
{ "key": "PUSH_NOTIFICATION_CB", "values": list containing the callback URL, if any }
Delete a registered push notification
Deletes the registered callback URL, if any.
HTTP Request
DELETE http://127.0.0.1:8080/1.0/kb/tenants/registerNotificationCallback
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/tenants/registerNotificationCallback"
import org.killbill.billing.client.api.gen.TenantApi;
protected TenantApi tenantApi;
tenantApi.deletePushNotificationCallbacks(requestOptions);
TODO
tenantApi = killbill.api.TenantApi()
tenantApi.delete_push_notification_callbacks(created_by='demo')
Example Response:
# Subset of headers returned when specifying -v curl option
< HTTP/1.1 204 No Content
< Content-Type: application/json
no content
no content
no content
Query Parameters
None.
Response
If successful, returns a status code of 204 and an empty body.
Tenant Key-Value Pairs
These endpoints provide a mechanism to register and manage {key, value}
pairs for a given tenant. This functionality
is used internally by the system to keep track of all the per-tenant configuration, including system properties, plugin configuration, and others discussed below. In addition, you can add user keys to keep track of additional information that may be desired. For example, some global setting that would be accessible for all plugins could be stored here.
Add a per tenant user key/value
This API adds a key-value pair to the tenant database. If the key already exists its value is replaced. The key is given as a path parameter.
HTTP Request
POST http://127.0.0.1:8080/1.0/kb/tenants/userKeyValue/{keyName}
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: application/json" \
-H "X-Killbill-CreatedBy: demo" \
-H "X-Killbill-Reason: demo" \
-H "X-Killbill-Comment: demo" \
-d "demo_value" \
"http://127.0.0.1:8080/1.0/kb/tenants/userKeyValue/demo_key"
import org.killbill.billing.client.api.gen.TenantApi;
protected TenantApi tenantApi;
String keyName = "demo_value";
String body = "demo_value";
TenantKeyValue result = tenantApi.insertUserKeyValue(keyName, body, requestOptions);
user = "demo"
reason = nil
comment = nil
key_name = "demo_value"
key_value = "demo_value"
KillBillClient::Model::Tenant.upload_tenant_user_key_value(key_name,
key_value,
user,
reason,
comment,
options)
tenantApi = killbill.api.TenantApi()
key_name = 'demo_value'
body = 'demo_value'
tenantApi.insert_user_key_value(key_name, body, created_by='demo')
Example Response:
# Subset of headers returned when specifying -v curl option
< HTTP/1.1 201 Created
< Location: http://localhost:8080/1.0/kb/tenants/userKeyValue/demo_key
< Content-Type: application/json
< Content-Length: 0
class TenantKeyValue {
key: demo_key
values: [demo_value]
}
{
"key":"demo_key",
"values":[
"demo_value"
]
}
no content
Request Body
The body contains a single string representing the value.
Query Parameters
None.
Response
If successful, returns a status code of 201 and an empty body. In addition, a Location
item is returned in the header giving the URL for this key-value pair.
Retrieve a per tenant user key value
Retrieves the value for a specified key, if it exists, from the tenant database. The key name is given as a path parameter.
HTTP Request
GET http://127.0.0.1:8080/1.0/kb/tenants/userKeyValue/{keyName}
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/tenants/userKeyValue/demo_value"
import org.killbill.billing.client.api.gen.TenantApi;
protected TenantApi tenantApi;
String keyName = "demo_value";
TenantKeyValue result = tenantApi.getUserKeyValue(keyName, requestOptions);
key_name = "demo_value"
KillBillClient::Model::Tenant.get_tenant_user_key_value(key_name, options)
tenantApi = killbill.api.TenantApi()
key_name = 'demo_value'
tenantApi.get_user_key_value(key_name)
Example Response:
# Subset of headers returned when specifying -v curl option
< HTTP/1.1 200 OK
< Content-Type: application/json
{
"key": "demo_value",
"values": [
"demo_value",
"demo_value"
]
}
class TenantKeyValue {
key: demo_value
values: [demo_value]
}
{
"key":"demo_value",
"values":[
"demo_value"
]
}
{'key': 'demo_value', 'values': []}
Query Parameters
None.
Response
If successful, returns a status code of 200 and a tenant key value object. The key value object includes the key name and a JSON array containing the value, if any, or a comma-separated list of values. For example:
{ "key": "MYKEY", "values": [ "value1", "value2" ] }
If the key does not exist no error is signalled but the values
list is empty.
Delete a per tenant user key/value
Deletes a key and its value, if it exists, from the tenant database. The key is given as a path parameter.
HTTP Request
DELETE http://127.0.0.1:8080/1.0/kb/tenants/userKeyValue/{keyName}
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/tenants/userKeyValue/demo_value"
import org.killbill.billing.client.api.gen.TenantApi;
protected TenantApi tenantApi;
String keyName = "demo_value";
tenantApi.deleteUserKeyValue(keyName, requestOptions);
user = "demo"
reason = nil
comment = nil
key_value = "demo_value"
KillBillClient::Model::Tenant.delete_tenant_user_key_value(key_value,
user,
reason,
comment,
options)
tenantApi = killbill.api.TenantApi()
key_name = 'demo_value'
tenantApi.delete_user_key_value(key_name, created_by='demo')
Example Response:
# Subset of headers returned when specifying -v curl option
< HTTP/1.1 204 No Content
< Content-Type: application/json
no content
no content
no content
Query Parameters
None.
Returns
If successful, returns a status code of 204 and an empty body. No error is signalled if the key does not exist.
Retrieve per tenant keys and values based on a key prefix
This API enables searching for existing keys based on a prefix of the key name. For example, a search string of "MYK" would match keys such as MYKEY1
, MYKEY2
, etc. The search string is given as a path parameter.
HTTP Request
GET http://127.0.0.1:8080/1.0/kb/tenants/uploadPerTenantConfig/{keyPrefix}/search
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/tenants/uploadPerTenantConfig/PER_TENANT/search"
import org.killbill.billing.client.api.gen.TenantApi;
protected TenantApi tenantApi;
String keyPrefix = "PER_TENANT";
TenantKeyValues result = tenantApi.getAllPluginConfiguration(keyPrefix, requestOptions);
key_prefix = "PER_TENANT"
KillBillClient::Model::Tenant.search_tenant_config(key_prefix, options)
tenantApi = killbill.api.TenantApi()
tenantApi.get_all_plugin_configuration(key_prefix='tenant_config')
Example Response:
# Subset of headers returned when specifying -v curl option
< HTTP/1.1 200 OK
< Content-Type: application/json
{
"key": "PER_TENANT_CONFIG",
"values": [
"{org.killbill.invoice.sanitySafetyBoundEnabled:false}"
]
}
class TenantKeyValue {
key: PER_TENANT_CONFIG
values: [
"{org.killbill.invoice.sanitySafetyBoundEnabled:false}"
]
}
TODO
{'key': 'PER_TENANT_CONFIG', 'values': [
"{org.killbill.invoice.sanitySafetyBoundEnabled:false}"
]}
Query Parameters
None.
Response
If successful, returns a status code of 200 and a tenant key value object containing the key and values for any keys that match the search string.
System Properties Configuration
These endpoints allow setting of some system properties on a per-tenant basis. Please refer to our configuartion guide to see what can be configured in the system. Some of the configuration can be overriden at the tenant level to allow for different behaviors.
Note that this is actually a special case of per-tenant key-value pairs; the key is "PER_TENANT_CONFIG" and the value is a comma-separated list of system properties with their values.
Add a per tenant system properties configuration
This API is used to set the value of specific system properties, overriding the system-wide values.
For example, in order to disable the invoice safety bound mechanism on a per-tenant level, this API could be used to set the per-tenant system property org.killbill.invoice.sanitySafetyBoundEnabled
to false.
The API sets the value of the "PER_TENANT_CONFIG" key, replacing any previous value.
HTTP Request
POST http://127.0.0.1:8080/1.0/kb/tenants/uploadPerTenantConfig
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: application/json" \
-H "X-Killbill-CreatedBy: demo" \
-H "X-Killbill-Reason: demo" \
-H "X-Killbill-Comment: demo" \
-d "{"org.killbill.invoice.sanitySafetyBoundEnabled":"false"}" \
"http://127.0.0.1:8080/1.0/kb/tenants/uploadPerTenantConfig"
import org.killbill.billing.client.api.gen.TenantApi;
protected TenantApi tenantApi;
String body = "{\"org.killbill.invoice.sanitySafetyBoundEnabled\":\"false\"}";
TenantKeyValue result = tenantApi.uploadPerTenantConfiguration(body, requestOptions);
TODO
tenantApi = killbill.api.TenantApi()
body = '{"org.killbill.invoice.sanitySafetyBoundEnabled":"false"}'
tenantApi.upload_per_tenant_configuration(body, created_by='demo')
Example Response:
# Subset of headers returned when specifying -v curl option
< HTTP/1.1 201 Created
< Location: http://localhost:8080/1.0/kb/tenants/uploadPerTenantConfig
< Content-Type: application/json
< Content-Length: 0
class TenantKeyValue {
key: PER_TENANT_CONFIG
values: [
"{org.killbill.invoice.sanitySafetyBoundEnabled:false}"
]
}
TODO
no content
Request Body
A JSON string representing the per-tenant system property and its value.
Query Parameters
None.
Response
If successful, returns a status code of 201 and an empty body.
Retrieve a per tenant system properties configuration
Retrieves the per-tenant system property settings, which are given as the value of the key PER_TENANT_CONFIG
.
HTTP Request
GET http://127.0.0.1:8080/1.0/kb/tenants/uploadPerTenantConfig
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/tenants/uploadPerTenantConfig"
import org.killbill.billing.client.api.gen.TenantApi;
protected TenantApi tenantApi;
TenantKeyValue result = tenantApi.getPerTenantConfiguration(requestOptions);
TODO
tenantApi = killbill.api.TenantApi()
tenantApi.get_per_tenant_configuration()
Example Response:
# Subset of headers returned when specifying -v curl option
< HTTP/1.1 200 OK
< Content-Type: application/json
{
"key": "PER_TENANT_CONFIG",
"values": [
"{org.killbill.invoice.sanitySafetyBoundEnabled:false}"
]
}
class TenantKeyValue {
key: PER_TENANT_CONFIG
values: [
"{org.killbill.invoice.sanitySafetyBoundEnabled:false}"
]
}
TODO
{'key': 'PER_TENANT_CONFIG', 'values': [
"{org.killbill.invoice.sanitySafetyBoundEnabled:false}"
]}
Query Parameters
None.
Response
If successful, returns a status code of 200 and a tenant key value object for the key PER_TENANT_CONFIG
.
Delete a per tenant system properties configuration
Deletes any current per tenant system properties configuration parameters, which are given as the values of the PER_TENANT_CONFIG
key.
HTTP Request
DELETE http://127.0.0.1:8080/1.0/kb/tenants/uploadPerTenantConfig
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/tenants/uploadPerTenantConfig"
import org.killbill.billing.client.api.gen.TenantApi;
protected TenantApi tenantApi;
tenantApi.deletePerTenantConfiguration(requestOptions);
TODO
tenantApi = killbill.api.TenantApi()
tenantApi.delete_per_tenant_configuration(created_by='demo')
Example Response:
# Subset of headers returned when specifying -v curl option
< HTTP/1.1 204 No Content
< Content-Type: application/json
no content
no content
no content
Query Parameters
None.
Response
If successful, returns a status code of 204 and an empty body.
Plugin Configuration
Plugins also support configuration on a per-tenant level. Please refer to our plugin configuration manual for more details.
An example of the use of such per-tenant properties is to configure a payment plugin with different API keys, one set of keys for each tenant. This allows for a true multi-tenant deployment where plugins have different configuration based on the tenant in which they operate.
Upon adding or deleting a new per-tenant plugin configuration, the system will generate a TENANT_CONFIG_CHANGE
/TENANT_CONFIG_DELETION
event, which can be handled in the plugin to refresh its configuration. In multi-node scenarios, events will be dispatched on each node, that is, on each plugin instance so they end up with a consistent view. A lot of the logic to handle configuration update has been implemented in our plugin frameworks (see ruby framework and java framework).
As with the system properties configuration, this is actually a special case of per-tenant key-value pairs. The following endpoints provide the ability to configure plugins on a per-tenant level.
Add a per tenant configuration for a plugin
Adds a per tenant key-value pair for the specified plugin. The plugin name is given as a path parameter. The key name is PLUGIN_CONFIG_*plugin*
where plugin is the plugin name. The API sets the value of this key, replacing any previous value.
The value string uploaded is plugin dependent but typically consists of key/value properties, or well formatted yml or a properties file.
HTTP Request
POST http://127.0.0.1:8080/1.0/kb/tenants/uploadPluginConfig/{pluginName}
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: application/json" \
-H "X-Killbill-CreatedBy: demo" \
-H "X-Killbill-Reason: demo" \
-H "X-Killbill-Comment: demo" \
-d @./config.properties \
"http://127.0.0.1:8080/1.0/kb/tenants/uploadPluginConfig/demo_plugin"
import org.killbill.billing.client.api.gen.TenantApi;
protected TenantApi tenantApi;
String pluginName = "PLUGIN_FOO";
String pluginConfig = "plugin configuration string";
TenantKeyValue result = tenantApi.uploadPluginConfiguration(pluginName, pluginConfig, requestOptions);
plugin_name = "demo_plugin"
plugin_config = "tenant_config"
user = "demo"
reason = nil
comment = nil
KillBillClient::Model::Tenant.upload_tenant_plugin_config(plugin_name,
plugin_config,
user,
reason,
comment,
options)
tenantApi = killbill.api.TenantApi()
plugin_name = 'demo_plugin'
body = 'tenant_config'
tenantApi.upload_plugin_configuration(plugin_name, body, created_by='demo')
Example Response:
# Subset of headers returned when specifying -v curl option
< HTTP/1.1 201 Created
< Location: http://localhost:8080/1.0/kb/tenants/uploadPluginConfig/demo_plugin
< Content-Type: application/json
< Content-Length: 0
class TenantKeyValue {
key: PLUGIN_CONFIG_PLUGIN_FOO
values:
:my_plugin:
:test: True
:log_file: /var/tmp/myplugin.log
:username: xx
:password: yoyoyo
:merchant_id:
:USD: '0689870'
:database:
:adapter: sqlite3
:database: test.db
]
}
{
"key":"PLUGIN_CONFIG_demo_plugin",
"values":[
"tenant_config"
]
}
no content
Request Body
The request body can be specified as a JSON string consisting of the key-value pairs for the plugin configuration. Alternatively, the plugin configuration can be specified in a yml or properties file and its path can be specified.
Query Parameters
None.
Response
If successful, returns a status code of 201 and an empty body. A Location
header is also returned giving the URL of the key-value pair.
Retrieve a per tenant configuration for a plugin
Gets the per tenant configuration value string for a specified plugin. The plugin name is given as a path parameter.
HTTP Request
GET http://127.0.0.1:8080/1.0/kb/tenants/uploadPluginConfig/{pluginName}
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/tenants/uploadPluginConfig/demo_plugin"
import org.killbill.billing.client.api.gen.TenantApi;
protected TenantApi tenantApi;
final String pluginName = "PLUGIN_FOO";
final TenantKeyValue result = tenantApi.getPluginConfiguration(pluginName, requestOptions);
plugin_name = "demo_plugin"
KillBillClient::Model::Tenant.get_tenant_plugin_config(plugin_name, options)
tenantApi = killbill.api.TenantApi()
plugin_name = 'demo_plugin'
tenantApi.get_plugin_configuration(plugin_name)
Example Response:
# Subset of headers returned when specifying -v curl option
< HTTP/1.1 200 OK
< Content-Type: application/json
{
"key": "PLUGIN_CONFIG_demo_plugin",
"values": [
"tenant_config"
]
}
class TenantKeyValue {
key: PLUGIN_CONFIG_PLUGIN_FOO
values:
:my_plugin:
:test: True
:log_file: /var/tmp/myplugin.log
:username: xx
:password: yoyoyo
:merchant_id:
:USD: '0689870'
:database:
:adapter: sqlite3
:database: test.db
]
}
{
"key":"PLUGIN_CONFIG_demo_plugin",
"values":[
"tenant_config"
]
}
{'key': 'PLUGIN_CONFIG_demo_plugin', 'values': []}
Query Parameters
None.
Response
If successful, returns a status code of 200 and a tenant key value object for the key PLUGIN_CONFIG_*plugin*
.
Delete a per tenant configuration for a plugin
Deletes the per tenant plugin configuration value for the appropriate key. The plugin name is given as a path parameter.
HTTP Request
DELETE http://127.0.0.1:8080/1.0/kb/tenants/uploadPluginConfig/{pluginName}
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/tenants/uploadPluginConfig/demo_plugin"
import org.killbill.billing.client.api.gen.TenantApi;
protected TenantApi tenantApi;
final String pluginName = "PLUGIN_FOO";
tenantApi.deletePluginConfiguration(pluginName, requestOptions);
user = "demo"
reason = nil
comment = nil
plugin_name = "demo_plugin"
KillBillClient::Model::Tenant.delete_tenant_plugin_config(plugin_name,
user,
reason,
comment,
options)
tenantApi = killbill.api.TenantApi()
plugin_name = 'demo_plugin'
tenantApi.delete_plugin_configuration(plugin_name, created_by='demo')
Example Response:
# Subset of headers returned when specifying -v curl option
< HTTP/1.1 204 No Content
< Content-Type: application/json
no content
no content
no content
Query Parameters
None.
Returns
If successful, returns a status code of 204 and an empty body.
Payment State Machines
This is a somewhat advanced use case to override the default internal payment state machine within Kill Bill. Please refer to our payment manual for more details about payment states.
The endpoints below allow you to override such state machines on a per-tenant level.
Add a per tenant payment state machine for a plugin
Adds a per tenant key-value pair for the specified plugin. The plugin name is given as a path parameter. The key name is PLUGIN_PAYMENT_STATE_MACHINE_*plugin*
where plugin is the plugin name. The API sets the value of this key, replacing any previous value.
The state machine is defined in an XML file. The complete XML file becomes the value of the key.
HTTP Request
Let's say we want to overwrite the default Kill Bill payment state machine for the payment plugin demo_plugin
, and assuming SimplePaymentStates.xml
is a valid payment state machine XML file, then the HTTP Request would be:
POST http://127.0.0.1:8080/1.0/kb/tenants/uploadPluginPaymentStateMachineConfig/{pluginName}
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: application/json" \
-H "X-Killbill-CreatedBy: demo" \
-H "X-Killbill-Reason: demo" \
-H "X-Killbill-Comment: demo" \
-d '@SimplePaymentStates.xml' \
"http://127.0.0.1:8080/1.0/kb/tenants/uploadPluginPaymentStateMachineConfig/demo_plugin"
import org.killbill.billing.client.api.gen.TenantApi;
protected TenantApi tenantApi;
String pluginName = "noop";
String stateMachineConfig = getResourceBodyString("SimplePaymentStates.xml");
TenantKeyValue result = tenantApi.uploadPluginPaymentStateMachineConfig(pluginName,
stateMachineConfig,
requestOptions);
TODO
tenantApi = killbill.api.TenantApi()
plugin_name = 'demo_plugin'
body = 'SimplePaymentStates.xml'
tenantApi.upload_plugin_payment_state_machine_config(plugin_name, body, created_by='demo')
Example Response:
# Subset of headers returned when specifying -v curl option
< HTTP/1.1 201 Created
< Location: http://localhost:8080/1.0/kb/tenants/uploadPluginPaymentStateMachineConfig/demo_plugin
< Content-Type: application/json
< Content-Length: 0
class TenantKeyValue {
key: PLUGIN_PAYMENT_STATE_MACHINE_noop
values: [<?xml version="1.0" encoding="UTF-8"?>
<stateMachineConfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="StateMachineConfig.xsd">
<stateMachines>
<stateMachine name="BIG_BANG">
<states>
<state name="BIG_BANG_INIT"/>
</states>
<transitions>
<transition>
<initialState>BIG_BANG_INIT</initialState>
<operation>OP_DUMMY</operation>
<operationResult>SUCCESS</operationResult>
<finalState>BIG_BANG_INIT</finalState>
</transition>
</transitions>
<operations>
<operation name="OP_DUMMY"/>
</operations>
</stateMachine>
<stateMachine name="AUTHORIZE">
<states>
<state name="AUTH_INIT"/>
<state name="AUTH_SUCCESS"/>
<state name="AUTH_FAILED"/>
<state name="AUTH_ERRORED"/>
</states>
<transitions>
<transition>
<initialState>AUTH_INIT</initialState>
<operation>OP_AUTHORIZE</operation>
<operationResult>SUCCESS</operationResult>
<finalState>AUTH_SUCCESS</finalState>
</transition>
<transition>
<initialState>AUTH_INIT</initialState>
<operation>OP_AUTHORIZE</operation>
<operationResult>FAILURE</operationResult>
<finalState>AUTH_FAILED</finalState>
</transition>
<transition>
<initialState>AUTH_INIT</initialState>
<operation>OP_AUTHORIZE</operation>
<operationResult>EXCEPTION</operationResult>
<finalState>AUTH_ERRORED</finalState>
</transition>
</transitions>
<operations>
<operation name="OP_AUTHORIZE"/>
</operations>
</stateMachine>
</stateMachines>
<linkStateMachines>
<linkStateMachine>
<initialStateMachine>BIG_BANG</initialStateMachine>
<initialState>BIG_BANG_INIT</initialState>
<finalStateMachine>AUTHORIZE</finalStateMachine>
<finalState>AUTH_INIT</finalState>
</linkStateMachine>
</linkStateMachines>
</stateMachineConfig>
]
}
TODO
no content
Query Parameters
None.
Response
If successful, returns a status code of 201 and an empty body. In addition, a Location
item is returned in the header giving the URL for the payment state machine.
Retrieve a per tenant payment state machine for a plugin
Retrieves the value for the appropriate payment state machine key for the specified plugin. If present, this value should be the complete XML file that defines the state machine.
HTTP Request
GET http://127.0.0.1:8080/1.0/kb/tenants/uploadPluginPaymentStateMachineConfig/{pluginName}
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/tenants/uploadPluginPaymentStateMachineConfig/demo_plugin"
import org.killbill.billing.client.api.gen.TenantApi;
protected TenantApi tenantApi;
String pluginName = "noop";
TenantKeyValue result = tenantApi.getPluginPaymentStateMachineConfig(pluginName, requestOptions);
TODO
tenantApi = killbill.api.TenantApi()
plugin_name = 'demo_plugin'
tenantApi.get_plugin_payment_state_machine_config(plugin_name)
Example Response:
# Subset of headers returned when specifying -v curl option
< HTTP/1.1 200 OK
< Content-Type: application/json
{
"key": "PLUGIN_PAYMENT_STATE_MACHINE_demo_plugin",
"values": [<?xml version="1.0" encoding="UTF-8"?>
<stateMachineConfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="StateMachineConfig.xsd">
<stateMachines>
<stateMachine name="BIG_BANG">
<states>
<state name="BIG_BANG_INIT"/>
</states>
<transitions>
<transition>
<initialState>BIG_BANG_INIT</initialState>
<operation>OP_DUMMY</operation>
<operationResult>SUCCESS</operationResult>
<finalState>BIG_BANG_INIT</finalState>
</transition>
</transitions>
<operations>
<operation name="OP_DUMMY"/>
</operations>
</stateMachine>
<stateMachine name="AUTHORIZE">
<states>
<state name="AUTH_INIT"/>
<state name="AUTH_SUCCESS"/>
<state name="AUTH_FAILED"/>
<state name="AUTH_ERRORED"/>
</states>
<transitions>
<transition>
<initialState>AUTH_INIT</initialState>
<operation>OP_AUTHORIZE</operation>
<operationResult>SUCCESS</operationResult>
<finalState>AUTH_SUCCESS</finalState>
</transition>
<transition>
<initialState>AUTH_INIT</initialState>
<operation>OP_AUTHORIZE</operation>
<operationResult>FAILURE</operationResult>
<finalState>AUTH_FAILED</finalState>
</transition>
<transition>
<initialState>AUTH_INIT</initialState>
<operation>OP_AUTHORIZE</operation>
<operationResult>EXCEPTION</operationResult>
<finalState>AUTH_ERRORED</finalState>
</transition>
</transitions>
<operations>
<operation name="OP_AUTHORIZE"/>
</operations>
</stateMachine>
</stateMachines>
<linkStateMachines>
<linkStateMachine>
<initialStateMachine>BIG_BANG</initialStateMachine>
<initialState>BIG_BANG_INIT</initialState>
<finalStateMachine>AUTHORIZE</finalStateMachine>
<finalState>AUTH_INIT</finalState>
</linkStateMachine>
</linkStateMachines>
</stateMachineConfig>
]
}
class TenantKeyValue {
key: PLUGIN_PAYMENT_STATE_MACHINE_noop
values: [<?xml version="1.0" encoding="UTF-8"?>
<stateMachineConfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="StateMachineConfig.xsd">
<stateMachines>
<stateMachine name="BIG_BANG">
<states>
<state name="BIG_BANG_INIT"/>
</states>
<transitions>
<transition>
<initialState>BIG_BANG_INIT</initialState>
<operation>OP_DUMMY</operation>
<operationResult>SUCCESS</operationResult>
<finalState>BIG_BANG_INIT</finalState>
</transition>
</transitions>
<operations>
<operation name="OP_DUMMY"/>
</operations>
</stateMachine>
<stateMachine name="AUTHORIZE">
<states>
<state name="AUTH_INIT"/>
<state name="AUTH_SUCCESS"/>
<state name="AUTH_FAILED"/>
<state name="AUTH_ERRORED"/>
</states>
<transitions>
<transition>
<initialState>AUTH_INIT</initialState>
<operation>OP_AUTHORIZE</operation>
<operationResult>SUCCESS</operationResult>
<finalState>AUTH_SUCCESS</finalState>
</transition>
<transition>
<initialState>AUTH_INIT</initialState>
<operation>OP_AUTHORIZE</operation>
<operationResult>FAILURE</operationResult>
<finalState>AUTH_FAILED</finalState>
</transition>
<transition>
<initialState>AUTH_INIT</initialState>
<operation>OP_AUTHORIZE</operation>
<operationResult>EXCEPTION</operationResult>
<finalState>AUTH_ERRORED</finalState>
</transition>
</transitions>
<operations>
<operation name="OP_AUTHORIZE"/>
</operations>
</stateMachine>
</stateMachines>
<linkStateMachines>
<linkStateMachine>
<initialStateMachine>BIG_BANG</initialStateMachine>
<initialState>BIG_BANG_INIT</initialState>
<finalStateMachine>AUTHORIZE</finalStateMachine>
<finalState>AUTH_INIT</finalState>
</linkStateMachine>
</linkStateMachines>
</stateMachineConfig>
]
}
TODO
{'key': 'PLUGIN_PAYMENT_STATE_MACHINE_demo_plugin', 'values': []}
Query Parameters
None.
Response
If successful, returns a status code of 200 and a key value object for the key PLUGIN_PAYMENT_STATE_MACHINE_*plugin*
. The value of this key should be the complete XML file that defines the payment state machine.
Delete a per tenant payment state machine for a plugin
Deletes the payment state machine for the specified plugin for this tenant. The plugin reverts to the default payment state machine.
HTTP Request
DELETE http://127.0.0.1:8080/1.0/kb/tenants/uploadPluginPaymentStateMachineConfig/{pluginName}
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://localhost:8080/1.0/kb/tenants/uploadPluginPaymentStateMachineConfig/demo_plugin"
import org.killbill.billing.client.api.gen.TenantApi;
protected TenantApi tenantApi;
String pluginName = "noop";
tenantApi.deletePluginPaymentStateMachineConfig(pluginName, requestOptions);
TODO
tenantApi = killbill.api.TenantApi()
plugin_name = 'demo_plugin'
tenantApi.delete_plugin_payment_state_machine_config(plugin_name, created_by='demo')
Example Response:
# Subset of headers returned when specifying -v curl option
< HTTP/1.1 204 No Content
< Content-Type: application/json
no content
no content
no content
Query Parameters
None.
Returns
If successful, returns a status code of 204 and an empty body.
Catalog
The Catalog
is at the heart of the Kill Bill subscription and billing systems. It provides complete current information on products available, subscription plans, billing options, and much more. Each tenant has a single catalog, but different tenants may have completely different catalogs.
The catalog for a given tenant may be updated to new versions from time to time. This provides the ability to deprecate old products, add new ones, or change prices for existing products. Older versions remain available in case they are needed. If a new version is uploaded, new subscriptions will use the new version, but existing subscriptions may either depend on their original versions (grandfathering use case) or use the latest version (price update use case). Please refer to the catalog section of our subscription billing documentation for additional details.
KAUI, our admin UI, provides the ability to upload a simple plan. The simple plan provides a way to ease testing and to play with the system. See API section Simple Plan.
A tenant has several options for setting up their catalog. You can choose the option that best meets your needs:
- Use the default test catalog that ships with Kill Bill by creating a tenant with
useGlobalDefault=true
- Use the Simple Plan API from KAUI to get started quickly (no need to create an XML catalog, simply use the UI and add the plans you need).
- Write your own complete catalog as an XML file and upload it. Some examples of catalog can be found in our test repo. For validation, check our manual or use our cloud validation tool after creating an account.
- Write a custom Catalog plugin. This is only for advanced users with special needs.
For a full discussion of the KillBill catalog, see the Catalog section in the Subscription Guide.
The Catalog
API offers basic CRUD operations, allowing you to upload, retrieve and delete catalog versions.
Catalog Resource
At a very high level, the Catalog consists of the following main components:
Products
: List of products available - e.g Gold product.Plans
: List of subscription plans available for each product - e.g gold-monthly, monthly subscription for the Gold product.Rules
: Business rules for subscriptions - e.g. when certain changes should take effect.Price Lists
: Lists of applicable Plans.
Full details about the elements of a Catalog are given in the links cited above. The Catalog is maintained as an XML file.
CatalogValidation Resource
Represents the result of validating a catalog.
It includes the following attribute:
Name | Type | Generated by | Description |
---|---|---|---|
catalogValidationErrors | list | system | List of CatalogValidationError (see next) |
CatalogValidationError:
Represents a catalog validation error.
It includes the following attributes:
Name | Type | Generated by | Description |
---|---|---|---|
errorDescription | string | system | Description about the error |
Catalog
Upload a catalog as XML
This endpoint uploads a complete catalog in XML format. This becomes the current version of the Catalog for this Tenant.
Note that the naming for the various entities is based on what the XML spec specifies, and in particular the name
elements need to be globally unique in the catalog and must conform to the XML NCName
definition. This means that they cannot contain symbol characters like :, @, $, %, &, /, +, ,, ;,, whitespace characters or parentheses, and they cannot begin with a number, dot or minus character.
HTTP Request
POST http://127.0.0.1:8080/1.0/kb/catalog/xml
Example Request:
curl -v \
-X POST \
-u admin:password \
-H "X-Killbill-ApiKey: bob" \
-H "X-Killbill-ApiSecret: lazar" \
-H "Content-Type: text/xml" \
-H "Accept: application/json" \
-H "X-Killbill-CreatedBy: demo" \
-H "X-Killbill-Reason: demo" \
-H "X-Killbill-Comment: demo" \
-d '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><catalog> ...' \
"http://127.0.0.1:8080/1.0/kb/catalog/xml"
import org.killbill.billing.client.api.gen.CatalogApi;
protected CatalogApi catalogApi;
String body = getResourceBodyString(catalog);
catalogApi.uploadCatalogXml(body, requestOptions);
catalog_file_xml = resource_file.read
KillBillClient::Model::Catalog.upload_tenant_catalog(catalog_file_xml,
user,
reason,
comment,
options)
catalogApi = killbill.api.CatalogApi()
xml_catalog = open("../resources/SpyCarBasic.xml", "r+").read()
catalogApi.upload_catalog_xml(xml_catalog,
created_by,
api_key,
api_secret)
Example Response:
# Subset of headers returned when specifying -v curl option
< HTTP/1.1 201 Created
< Location: http://localhost:8080/1.0/kb/catalog/xml
< Content-Type: text/xml
< Content-Length: 0
no content
no content
no content
Request Body
Contains the complete catalog in XML format
Query Parameters
None.
Response
If successful, returns a status code of 201 and an empty body.
Retrieve the catalog as XML
This endpoint retrieves the Catalog for a specified date in XML format. If there are multiple versions, the latest version with an effective date not later than the requested date is returned. If the effective date for all versions is greater than the requested date, the earliest version is returned.
For example, suppose there are two versions of the catalog, the current version dated 2020-01-01 (Jan. 1, 2020) and a previous version dated 2019-01-01. Then
- A request with no effective date would retrieve the current version
- A request with an effective date of 2020-01-01 or later would retrieve the current version
- A request with an effective date of 2019-01-01 or later, but before 2020-01-01, would retrieve the previous version
- A request with an effective date earlier than 2019-01-01 would retrieve the previous version, as it is the earliest version available.
HTTP Request
GET http://127.0.0.1:8080/1.0/kb/catalog/xml
Example Request:
curl -v \
-u admin:password \
-H "X-Killbill-ApiKey: bob" \
-H "X-Killbill-ApiSecret: lazar" \
-H "Accept: text/xml" \
"http://localhost:8080/1.0/kb/catalog/xml"
import org.killbill.billing.client.api.gen.CatalogApi;
protected CatalogApi catalogApi;
LocalDate requestedDate = null;
UUID accountId = null;
String catalog = catalogApi.getCatalogXml(requestedDate,
accountId,
requestOptions);
requested_date = nil
KillBillClient::Model::Catalog.get_tenant_catalog_xml(requested_date,
options)
catalogApi = killbill.api.CatalogApi()
catalogApi.get_catalog_xml(api_key, api_secret)
Example Response:
# Subset of headers returned when specifying -v curl option
< HTTP/1.1 200 OK
< Content-Type: text/xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<catalogs>
<versions>
<version>
<effectiveDate>2013-02-08T00:00:00Z</effectiveDate>
<catalogName>SpyCarBasic</catalogName>
<currencies>
<currency>USD</currency>
<currency>GBP</currency>
</currencies>
<units/>
<products>
<product name="Basic" prettyName="Basic">
<category>BASE</category>
<included/>
<available/>
<limits/>
</product>
<product name="Sports" prettyName="Sports">
<category>BASE</category>
<included/>
<available/>
<limits/>
</product>
<product name="Standard" prettyName="Standard">
<category>BASE</category>
<included/>
<available/>
<limits/>
</product>
<product name="Super" prettyName="Super">
<category>ADD_ON</category>
<included/>
<available/>
<limits/>
</product>
</products>
<rules>
<changePolicy>
<changePolicyCase>
<policy>IMMEDIATE</policy>
</changePolicyCase>
</changePolicy>
<changeAlignment>
<changeAlignmentCase>
<alignment>START_OF_BUNDLE</alignment>
</changeAlignmentCase>
</changeAlignment>
<cancelPolicy>
<cancelPolicyCase>
<policy>IMMEDIATE</policy>
</cancelPolicyCase>
</cancelPolicy>
<createAlignment>
<createAlignmentCase>
<alignment>START_OF_BUNDLE</alignment>
</createAlignmentCase>
</createAlignment>
<billingAlignment>
<billingAlignmentCase>
<alignment>ACCOUNT</alignment>
</billingAlignmentCase>
</billingAlignment>
<priceList>
<priceListCase>
<toPriceList>DEFAULT</toPriceList>
</priceListCase>
</priceList>
</rules>
<plans>
<plan name="basic-annual" prettyName="basic-annual">
<product>Basic</product>
<recurringBillingMode>IN_ADVANCE</recurringBillingMode>
<initialPhases/>
<finalPhase type="EVERGREEN">
<duration>
<unit>UNLIMITED</unit>
<number>-1</number>
</duration>
<recurring>
<billingPeriod>ANNUAL</billingPeriod>
<recurringPrice>
<price>
<currency>USD</currency>
<value>1000</value>
</price>
</recurringPrice>
</recurring>
<usages/>
</finalPhase>
<plansAllowedInBundle>-1</plansAllowedInBundle>
</plan>
<plan name="sports-monthly" prettyName="sports-monthly">
<product>Sports</product>
<recurringBillingMode>IN_ADVANCE</recurringBillingMode>
<initialPhases>
<phase type="TRIAL">
<duration>
<unit>DAYS</unit>
<number>30</number>
</duration>
<fixed type="ONE_TIME">
<fixedPrice/>
</fixed>
<usages/>
</phase>
</initialPhases>
<finalPhase type="EVERGREEN">
<duration>
<unit>UNLIMITED</unit>
<number>-1</number>
</duration>
<recurring>
<billingPeriod>MONTHLY</billingPeriod>
<recurringPrice>
<price>
<currency>GBP</currency>
<value>375.00</value>
</price>
<price>
<currency>USD</currency>
<value>500.00</value>
</price>
</recurringPrice>
</recurring>
<usages/>
</finalPhase>
<plansAllowedInBundle>-1</plansAllowedInBundle>
</plan>
<plan name="standard-monthly" prettyName="standard-monthly">
<product>Standard</product>
<recurringBillingMode>IN_ADVANCE</recurringBillingMode>
<initialPhases>
<phase type="TRIAL">
<duration>
<unit>DAYS</unit>
<number>30</number>
</duration>
<fixed type="ONE_TIME">
<fixedPrice/>
</fixed>
<usages/>
</phase>
</initialPhases>
<finalPhase type="EVERGREEN">
<duration>
<unit>UNLIMITED</unit>
<number>-1</number>
</duration>
<recurring>
<billingPeriod>MONTHLY</billingPeriod>
<recurringPrice>
<price>
<currency>GBP</currency>
<value>75.00</value>
</price>
<price>
<currency>USD</currency>
<value>100.00</value>
</price>
</recurringPrice>
</recurring>
<usages/>
</finalPhase>
<plansAllowedInBundle>-1</plansAllowedInBundle>
</plan>
<plan name="super-monthly" prettyName="super-monthly">
<product>Super</product>
<recurringBillingMode>IN_ADVANCE</recurringBillingMode>
<initialPhases>
<phase type="TRIAL">
<duration>
<unit>DAYS</unit>
<number>30</number>
</duration>
<fixed type="ONE_TIME">
<fixedPrice/>
</fixed>
<usages/>
</phase>
</initialPhases>
<finalPhase type="EVERGREEN">
<duration>
<unit>UNLIMITED</unit>
<number>-1</number>
</duration>
<recurring>
<billingPeriod>MONTHLY</billingPeriod>
<recurringPrice>
<price>
<currency>GBP</currency>
<value>750.00</value>
</price>
<price>
<currency>USD</currency>
<value>1000.00</value>
</price>
</recurringPrice>
</recurring>
<usages/>
</finalPhase>
<plansAllowedInBundle>-1</plansAllowedInBundle>
</plan>
</plans>
<priceLists>
<defaultPriceList name="DEFAULT">
<plans>
<plan>basic-annual</plan>
<plan>sports-monthly</plan>
<plan>standard-monthly</plan>
<plan>super-monthly</plan>
</plans>
</defaultPriceList>
</priceLists>
</version>
</versions>
<catalogName>SpyCarBasic</catalogName>
</catalogs>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<catalogs>
<versions>
<version>
<effectiveDate>2013-02-08T00:00:00Z</effectiveDate>
<catalogName>SpyCarBasic</catalogName>
<currencies>
<currency>USD</currency>
<currency>GBP</currency>
</currencies>
<units/>
<products>
<product name="Sports" prettyName="Sports">
<category>BASE</category>
<included/>
<available/>
<limits/>
</product>
<product name="Standard" prettyName="Standard">
<category>BASE</category>
<included/>
<available/>
<limits/>
</product>
<product name="Super" prettyName="Super">
<category>BASE</category>
<included/>
<available/>
<limits/>
</product>
</products>
<rules>
<changePolicy>
<changePolicyCase>
<policy>IMMEDIATE</policy>
</changePolicyCase>
</changePolicy>
<changeAlignment>
<changeAlignmentCase>
<alignment>START_OF_BUNDLE</alignment>
</changeAlignmentCase>
</changeAlignment>
<cancelPolicy>
<cancelPolicyCase>
<policy>IMMEDIATE</policy>
</cancelPolicyCase>
</cancelPolicy>
<createAlignment>
<createAlignmentCase>
<alignment>START_OF_BUNDLE</alignment>
</createAlignmentCase>
</createAlignment>
<billingAlignment>
<billingAlignmentCase>
<alignment>ACCOUNT</alignment>
</billingAlignmentCase>
</billingAlignment>
<priceList>
<priceListCase>
<toPriceList>DEFAULT</toPriceList>
</priceListCase>
</priceList>
</rules>
<plans>
<plan name="sports-monthly" prettyName="sports-monthly">
<product>Sports</product>
<recurringBillingMode>IN_ADVANCE</recurringBillingMode>
<initialPhases>
<phase type="TRIAL">
<duration>
<unit>DAYS</unit>
<number>30</number>
</duration>
<fixed type="ONE_TIME">
<fixedPrice/>
</fixed>
<usages/>
</phase>
</initialPhases>
<finalPhase type="EVERGREEN">
<duration>
<unit>UNLIMITED</unit>
<number>-1</number>
</duration>
<recurring>
<billingPeriod>MONTHLY</billingPeriod>
<recurringPrice>
<price>
<currency>GBP</currency>
<value>375.00</value>
</price>
<price>
<currency>USD</currency>
<value>500.00</value>
</price>
</recurringPrice>
</recurring>
<usages/>
</finalPhase>
<plansAllowedInBundle>-1</plansAllowedInBundle>
</plan>
<plan name="standard-monthly" prettyName="standard-monthly">
<product>Standard</product>
<recurringBillingMode>IN_ADVANCE</recurringBillingMode>
<initialPhases>
<phase type="TRIAL">
<duration>
<unit>DAYS</unit>
<number>30</number>
</duration>
<fixed type="ONE_TIME">
<fixedPrice/>
</fixed>
<usages/>
</phase>
</initialPhases>
<finalPhase type="EVERGREEN">
<duration>
<unit>UNLIMITED</unit>
<number>-1</number>
</duration>
<recurring>
<billingPeriod>MONTHLY</billingPeriod>
<recurringPrice>
<price>
<currency>GBP</currency>
<value>75.00</value>
</price>
<price>
<currency>USD</currency>
<value>100.00</value>
</price>
</recurringPrice>
</recurring>
<usages/>
</finalPhase>
<plansAllowedInBundle>-1</plansAllowedInBundle>
</plan>
<plan name="super-monthly" prettyName="super-monthly">
<product>Super</product>
<recurringBillingMode>IN_ADVANCE</recurringBillingMode>
<initialPhases>
<phase type="TRIAL">
<duration>
<unit>DAYS</unit>
<number>30</number>
</duration>
<fixed type="ONE_TIME">
<fixedPrice/>
</fixed>
<usages/>
</phase>
</initialPhases>
<finalPhase type="EVERGREEN">
<duration>
<unit>UNLIMITED</unit>
<number>-1</number>
</duration>
<recurring>
<billingPeriod>MONTHLY</billingPeriod>
<recurringPrice>
<price>
<currency>GBP</currency>
<value>750.00</value>
</price>
<price>
<currency>USD</currency>
<value>1000.00</value>
</price>
</recurringPrice>
</recurring>
<usages/>
</finalPhase>
<plansAllowedInBundle>-1</plansAllowedInBundle>
</plan>
</plans>
<priceLists>
<defaultPriceList name="DEFAULT">
<plans>
<plan>sports-monthly</plan>
<plan>standard-monthly</plan>
<plan>super-monthly</plan>
</plans>
</defaultPriceList>
</priceLists>
</version>
</versions>
<catalogName>SpyCarBasic</catalogName>
</catalogs>
<?xml version="1.0" encoding="UTF-8"?>
<catalogs>
<versions>
<version>
<effectiveDate>2013-02-08T00:00:00Z</effectiveDate>
<catalogName>Movies</catalogName>
<recurringBillingMode>IN_ADVANCE</recurringBillingMode>
<currencies>
<currency>USD</currency>
</currencies>
<units />
<products>
<product name="Basic">
<category>BASE</category>
<included />
<available />
<limits />
</product>
</products>
<rules>
<changePolicy>
<changePolicyCase>
<policy>END_OF_TERM</policy>
</changePolicyCase>
</changePolicy>
<changeAlignment>
<changeAlignmentCase>
<alignment>START_OF_BUNDLE</alignment>
</changeAlignmentCase>
</changeAlignment>
<cancelPolicy>
<cancelPolicyCase>
<productCategory>BASE</productCategory>
<policy>END_OF_TERM</policy>
</cancelPolicyCase>
<cancelPolicyCase>
<policy>IMMEDIATE</policy>
</cancelPolicyCase>
</cancelPolicy>
<createAlignment>
<createAlignmentCase>
<alignment>START_OF_BUNDLE</alignment>
</createAlignmentCase>
</createAlignment>
<billingAlignment>
<billingAlignmentCase>
<alignment>ACCOUNT</alignment>
</billingAlignmentCase>
</billingAlignment>
<priceList>
<priceListCase>
<toPriceList>DEFAULT</toPriceList>
</priceListCase>
</priceList>
</rules>
<plans>
<plan name="basic-monthly">
<product>Basic</product>
<initialPhases />
<finalPhase type="EVERGREEN">
<duration>
<unit>UNLIMITED</unit>
<number>-1</number>
</duration>
<recurring>
<billingPeriod>MONTHLY</billingPeriod>
<recurringPrice>
<price>
<currency>USD</currency>
<value>1000.00</value>
</price>
</recurringPrice>
</recurring>
<usages />
</finalPhase>
<plansAllowedInBundle>-1</plansAllowedInBundle>
</plan>
</plans>
<priceLists>
<defaultPriceList name="DEFAULT">
<plans>
<plan>basic-monthly</plan>
</plans>
</defaultPriceList>
</priceLists>
</version>
<version>
<effectiveDate>2013-02-08T00:00:01Z</effectiveDate>
<catalogName>Movies</catalogName>
<recurringBillingMode>IN_ADVANCE</recurringBillingMode>
<currencies>
<currency>USD</currency>
</currencies>
<units />
<products>
<product name="Basic">
<category>BASE</category>
<included />
<available />
<limits />
</product>
</products>
<rules>
<changePolicy>
<changePolicyCase>
<policy>END_OF_TERM</policy>
</changePolicyCase>
</changePolicy>
<changeAlignment>
<changeAlignmentCase>
<alignment>START_OF_BUNDLE</alignment>
</changeAlignmentCase>
</changeAlignment>
<cancelPolicy>
<cancelPolicyCase>
<productCategory>BASE</productCategory>
<policy>END_OF_TERM</policy>
</cancelPolicyCase>
<cancelPolicyCase>
<policy>IMMEDIATE</policy>
</cancelPolicyCase>
</cancelPolicy>
<createAlignment>
<createAlignmentCase>
<alignment>START_OF_BUNDLE</alignment>
</createAlignmentCase>
</createAlignment>
<billingAlignment>
<billingAlignmentCase>
<alignment>ACCOUNT</alignment>
</billingAlignmentCase>
</billingAlignment>
<priceList>
<priceListCase>
<toPriceList>DEFAULT</toPriceList>
</priceListCase>
</priceList>
</rules>
<plans>
<plan name="basic-monthly">
<product>Basic</product>
<initialPhases>
<phase type="TRIAL">
<duration>
<unit>DAYS</unit>
<number>30</number>
</duration>
<fixed type="ONE_TIME">
<fixedPrice />
</fixed>
<usages />
</phase>
</initialPhases>
<finalPhase type="EVERGREEN">
<duration>
<unit>UNLIMITED</unit>
<number>-1</number>
</duration>
<recurring>
<billingPeriod>MONTHLY</billingPeriod>
<recurringPrice>
<price>
<currency>USD</currency>
<value>1000.00</value>
</price>
</recurringPrice>
</recurring>
<usages />
</finalPhase>
<plansAllowedInBundle>-1</plansAllowedInBundle>
</plan>
</plans>
<priceLists>
<defaultPriceList name="DEFAULT">
<plans>
<plan>basic-monthly</plan>
</plans>
</defaultPriceList>
</priceLists>
</version>
</versions>
<catalogName>Movies</catalogName>
<recurringBillingMode>IN_ADVANCE</recurringBillingMode>
</catalogs>
<?xml version="1.0" encoding="UTF-8"?>
<catalogs>
<versions>
<version>
<effectiveDate>2013-02-08T00:00:00Z</effectiveDate>
<catalogName>Movies</catalogName>
<recurringBillingMode>IN_ADVANCE</recurringBillingMode>
<currencies>
<currency>USD</currency>
</currencies>
<units />
<products>
<product name="Basic">
<category>BASE</category>
<included />
<available />
<limits />
</product>
</products>
<rules>
<changePolicy>
<changePolicyCase>
<policy>END_OF_TERM</policy>
</changePolicyCase>
</changePolicy>
<changeAlignment>
<changeAlignmentCase>
<alignment>START_OF_BUNDLE</alignment>
</changeAlignmentCase>
</changeAlignment>
<cancelPolicy>
<cancelPolicyCase>
<productCategory>BASE</productCategory>
<policy>END_OF_TERM</policy>
</cancelPolicyCase>
<cancelPolicyCase>
<policy>IMMEDIATE</policy>
</cancelPolicyCase>
</cancelPolicy>
<createAlignment>
<createAlignmentCase>
<alignment>START_OF_BUNDLE</alignment>
</createAlignmentCase>
</createAlignment>
<billingAlignment>
<billingAlignmentCase>
<alignment>ACCOUNT</alignment>
</billingAlignmentCase>
</billingAlignment>
<priceList>
<priceListCase>
<toPriceList>DEFAULT</toPriceList>
</priceListCase>
</priceList>
</rules>
<plans>
<plan name="basic-monthly">
<product>Basic</product>
<initialPhases />
<finalPhase type="EVERGREEN">
<duration>
<unit>UNLIMITED</unit>
<number>-1</number>
</duration>
<recurring>
<billingPeriod>MONTHLY</billingPeriod>
<recurringPrice>
<price>
<currency>USD</currency>
<value>1000.00</value>
</price>
</recurringPrice>
</recurring>
<usages />
</finalPhase>
<plansAllowedInBundle>-1</plansAllowedInBundle>
</plan>
</plans>
<priceLists>
<defaultPriceList name="DEFAULT">
<plans>
<plan>basic-monthly</plan>
</plans>
</defaultPriceList>
</priceLists>
</version>
<version>
<effectiveDate>2013-02-08T00:00:01Z</effectiveDate>
<catalogName>Movies</catalogName>
<recurringBillingMode>IN_ADVANCE</recurringBillingMode>
<currencies>
<currency>USD</currency>
</currencies>
<units />
<products>
<product name="Basic">
<category>BASE</category>
<included />
<available />
<limits />
</product>
</products>
<rules>
<changePolicy>
<changePolicyCase>
<policy>END_OF_TERM</policy>
</changePolicyCase>
</changePolicy>
<changeAlignment>
<changeAlignmentCase>
<alignment>START_OF_BUNDLE</alignment>
</changeAlignmentCase>
</changeAlignment>
<cancelPolicy>
<cancelPolicyCase>
<productCategory>BASE</productCategory>
<policy>END_OF_TERM</policy>
</cancelPolicyCase>
<cancelPolicyCase>
<policy>IMMEDIATE</policy>
</cancelPolicyCase>
</cancelPolicy>
<createAlignment>
<createAlignmentCase>
<alignment>START_OF_BUNDLE</alignment>
</createAlignmentCase>
</createAlignment>
<billingAlignment>
<billingAlignmentCase>
<alignment>ACCOUNT</alignment>
</billingAlignmentCase>
</billingAlignment>
<priceList>
<priceListCase>
<toPriceList>DEFAULT</toPriceList>
</priceListCase>
</priceList>
</rules>
<plans>
<plan name="basic-monthly">
<product>Basic</product>
<initialPhases>
<phase type="TRIAL">
<duration>
<unit>DAYS</unit>
<number>30</number>
</duration>
<fixed type="ONE_TIME">
<fixedPrice />
</fixed>
<usages />
</phase>
</initialPhases>
<finalPhase type="EVERGREEN">
<duration>
<unit>UNLIMITED</unit>
<number>-1</number>
</duration>
<recurring>
<billingPeriod>MONTHLY</billingPeriod>
<recurringPrice>
<price>
<currency>USD</currency>
<value>1000.00</value>
</price>
</recurringPrice>
</recurring>
<usages />
</finalPhase>
<plansAllowedInBundle>-1</plansAllowedInBundle>
</plan>
</plans>
<priceLists>
<defaultPriceList name="DEFAULT">
<plans>
<plan>basic-monthly</plan>
</plans>
</defaultPriceList>
</priceLists>
</version>
</versions>
<catalogName>Movies</catalogName>
<recurringBillingMode>IN_ADVANCE</recurringBillingMode>
</catalogs>
Query Parameters
Name | Type | Required | Default | Description |
---|---|---|---|---|
requestedDate | string | false | current date | requested date |
Response
If successful, returns a status code of 200 and the catalog for the requested date in XML format.
Retrieve the catalog as JSON
This endpoint retrieves the Catalog for a requested date in JSON format. If there are multiple versions, the latest version with an effective date not later than the requested date is returned. If the effective date for all versions is greater than the requested date, the earliest version is returned. See the previous endpoint for examples.
HTTP Request
GET http://127.0.0.1:8080/1.0/kb/catalog
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/catalog"
import org.killbill.billing.client.api.gen.CatalogApi;
protected CatalogApi catalogApi;
DateTime requestedDate = null;
UUID accountId = null;
Catalogs catalogsJson = catalogApi.getCatalogJson(requestedDate,
accountId,
requestOptions);
requested_date = nil
KillBillClient::Model::Catalog.get_tenant_catalog_json.(requested_date,
options)
catalogApi = killbill.api.CatalogApi()
catalogApi.get_catalog_json(api_key, api_secret)
Example Response:
# Subset of headers returned when specifying -v curl option
< HTTP/1.1 200 OK
< Content-Type: application/json
[
{
"name": "SpyCarBasic",
"effectiveDate": "2013-02-08T00:00:00.000+0000",
"currencies": [
"USD",
"GBP"
],
"units": [],
"products": [
{
"type": "ADD_ON",
"name": "Super",
"prettyName": "Super",
"plans": [
{
"name": "super-monthly",
"prettyName": "super-monthly",
"billingPeriod": "MONTHLY",
"phases": [
{
"type": "TRIAL",
"prices": [],
"fixedPrices": [],
"duration": {
"unit": "DAYS",
"number": 30
},
"usages": []
},
{
"type": "EVERGREEN",
"prices": [
{
"currency": "GBP",
"value": 750
},
{
"currency": "USD",
"value": 1000
}
],
"fixedPrices": [],
"duration": {
"unit": "UNLIMITED",
"number": -1
},
"usages": []
}
]
}
],
"included": [],
"available": []
},
{
"type": "BASE",
"name": "Standard",
"prettyName": "Standard",
"plans": [
{
"name": "standard-monthly",
"prettyName": "standard-monthly",
"billingPeriod": "MONTHLY",
"phases": [
{
"type": "TRIAL",
"prices": [],
"fixedPrices": [],
"duration": {
"unit": "DAYS",
"number": 30
},
"usages": []
},
{
"type": "EVERGREEN",
"prices": [
{
"currency": "GBP",
"value": 75
},
{
"currency": "USD",
"value": 100
}
],
"fixedPrices": [],
"duration": {
"unit": "UNLIMITED",
"number": -1
},
"usages": []
}
]
}
],
"included": [],
"available": []
},
{
"type": "BASE",
"name": "Sports",
"prettyName": "Sports",
"plans": [
{
"name": "sports-monthly",
"prettyName": "sports-monthly",
"billingPeriod": "MONTHLY",
"phases": [
{
"type": "TRIAL",
"prices": [],
"fixedPrices": [],
"duration": {
"unit": "DAYS",
"number": 30
},
"usages": []
},
{
"type": "EVERGREEN",
"prices": [
{
"currency": "GBP",
"value": 375
},
{
"currency": "USD",
"value": 500
}
],
"fixedPrices": [],
"duration": {
"unit": "UNLIMITED",
"number": -1
},
"usages": []
}
]
}
],
"included": [],
"available": []
}
],
"priceLists": [
{
"name": "DEFAULT",
"plans": [
"sports-monthly",
"standard-monthly",
"super-monthly"
]
}
]
}
]
class Catalog {
name: Firearms
effectiveDate: 2011-01-01T00:00:00.000Z
currencies: [USD, EUR, GBP]
units: [class Unit {
name: bullets
prettyName: bullets
}, class Unit {
name: stones
prettyName: stones
}]
products: [class Product {
type: BASE
name: Assault-Rifle
prettyName: Assault-Rifle
plans: [class Plan {
name: assault-rifle-annual
prettyName: assault-rifle-annual
billingPeriod: ANNUAL
phases: [class Phase {
type: TRIAL
prices: []
fixedPrices: []
duration: class Duration {
unit: DAYS
number: 30
}
usages: []
}, class Phase {
type: EVERGREEN
prices: [class Price {
currency: USD
value: 5999.95
}, class Price {
currency: EUR
value: 3499.95
}, class Price {
currency: GBP
value: 3999.95
}]
fixedPrices: []
duration: class Duration {
unit: UNLIMITED
number: -1
}
usages: []
}]
}, class Plan {
name: assault-rifle-annual-gunclub-discount
prettyName: assault-rifle-annual-gunclub-discount
billingPeriod: ANNUAL
phases: [class Phase {
type: TRIAL
prices: []
fixedPrices: []
duration: class Duration {
unit: DAYS
number: 30
}
usages: []
}, class Phase {
type: DISCOUNT
prices: [class Price {
currency: USD
value: 99.95
}, class Price {
currency: EUR
value: 99.95
}, class Price {
currency: GBP
value: 99.95
}]
fixedPrices: []
duration: class Duration {
unit: MONTHS
number: 6
}
usages: []
}, class Phase {
type: EVERGREEN
prices: [class Price {
currency: USD
value: 5999.95
}, class Price {
currency: EUR
value: 3499.95
}, class Price {
currency: GBP
value: 3999.95
}]
fixedPrices: []
duration: class Duration {
unit: UNLIMITED
number: -1
}
usages: []
}]
}, class Plan {
name: assault-rifle-annual-rescue
prettyName: assault-rifle-annual-rescue
billingPeriod: ANNUAL
phases: [class Phase {
type: DISCOUNT
prices: [class Price {
currency: USD
value: 5999.95
}, class Price {
currency: EUR
value: 3499.95
}, class Price {
currency: GBP
value: 3999.95
}]
fixedPrices: []
duration: class Duration {
unit: YEARS
number: 1
}
usages: []
}, class Phase {
type: EVERGREEN
prices: [class Price {
currency: USD
value: 5999.95
}, class Price {
currency: EUR
value: 3499.95
}, class Price {
currency: GBP
value: 3999.95
}]
fixedPrices: []
duration: class Duration {
unit: UNLIMITED
number: -1
}
usages: []
}]
}, class Plan {
name: assault-rifle-monthly
prettyName: assault-rifle-monthly
billingPeriod: MONTHLY
phases: [class Phase {
type: TRIAL
prices: []
fixedPrices: []
duration: class Duration {
unit: DAYS
number: 30
}
usages: []
}, class Phase {
type: EVERGREEN
prices: [class Price {
currency: USD
value: 599.95
}, class Price {
currency: EUR
value: 349.95
}, class Price {
currency: GBP
value: 399.95
}]
fixedPrices: []
duration: class Duration {
unit: UNLIMITED
number: -1
}
usages: []
}]
}]
included: [Cleaning, Telescopic-Scope]
available: [Bullets, Laser-Scope]
}, class Product {
type: ADD_ON
name: Holster
prettyName: Holster
plans: [class Plan {
name: holster-monthly-regular
prettyName: holster-monthly-regular
billingPeriod: MONTHLY
phases: [class Phase {
type: TRIAL
prices: []
fixedPrices: []
duration: class Duration {
unit: DAYS
number: 30
}
usages: []
}, class Phase {
type: EVERGREEN
prices: [class Price {
currency: USD
value: 199.95
}, class Price {
currency: EUR
value: 199.95
}, class Price {
currency: GBP
value: 199.95
}]
fixedPrices: []
duration: class Duration {
unit: UNLIMITED
number: -1
}
usages: []
}]
}, class Plan {
name: holster-monthly-special
prettyName: holster-monthly-special
billingPeriod: ANNUAL
phases: [class Phase {
type: TRIAL
prices: []
fixedPrices: []
duration: class Duration {
unit: DAYS
number: 30
}
usages: []
}, class Phase {
type: EVERGREEN
prices: [class Price {
currency: USD
value: 199.95
}, class Price {
currency: EUR
value: 199.95
}, class Price {
currency: GBP
value: 199.95
}]
fixedPrices: []
duration: class Duration {
unit: UNLIMITED
number: -1
}
usages: []
}]
}]
included: []
available: []
}, class Product {
type: ADD_ON
name: Refurbish-Maintenance
prettyName: Refurbish-Maintenance
plans: [class Plan {
name: refurbish-maintenance
prettyName: refurbish-maintenance
billingPeriod: MONTHLY
phases: [class Phase {
type: FIXEDTERM
prices: [class Price {
currency: USD
value: 199.95
}, class Price {
currency: EUR
value: 199.95
}, class Price {
currency: GBP
value: 199.95
}]
fixedPrices: [class Price {
currency: USD
value: 599.95
}, class Price {
currency: EUR
value: 599.95
}, class Price {
currency: GBP
value: 599.95
}]
duration: class Duration {
unit: MONTHS
number: 12
}
usages: []
}]
}]
included: []
available: []
}, class Product {
type: BASE
name: Trebuchet
prettyName: Trebuchet
plans: [class Plan {
name: trebuchet-usage-in-arrear
prettyName: Trebuchet Monthly Plan
billingPeriod: NO_BILLING_PERIOD
phases: [class Phase {
type: EVERGREEN
prices: []
fixedPrices: []
duration: class Duration {
unit: UNLIMITED
number: -1
}
usages: [class Usage {
billingPeriod: MONTHLY
tiers: [class Tier {
limits: [class Limit {
unit: stones
max: 100.0
min: -1.0
}]
fixedPrice: []
recurringPrice: [class Price {
currency: USD
value: 100
}]
blocks: []
}, class Tier {
limits: [class Limit {
unit: stones
max: -1.0
min: -1.0
}]
fixedPrice: []
recurringPrice: [class Price {
currency: USD
value: 1000
}]
blocks: []
}]
}]
}]
}]
included: []
available: []
}, class Product {
type: BASE
name: Blowdart
prettyName: Blowdart
plans: [class Plan {
name: blowdart-monthly
prettyName: blowdart-monthly
billingPeriod: MONTHLY
phases: [class Phase {
type: TRIAL
prices: []
fixedPrices: []
duration: class Duration {
unit: DAYS
number: 30
}
usages: []
}, class Phase {
type: DISCOUNT
prices: [class Price {
currency: USD
value: 9.95
}, class Price {
currency: EUR
value: 9.95
}, class Price {
currency: GBP
value: 9.95
}]
fixedPrices: []
duration: class Duration {
unit: MONTHS
number: 6
}
usages: []
}, class Phase {
type: EVERGREEN
prices: [class Price {
currency: USD
value: 29.95
}, class Price {
currency: EUR
value: 29.95
}, class Price {
currency: GBP
value: 29.95
}]
fixedPrices: []
duration: class Duration {
unit: UNLIMITED
number: -1
}
usages: []
}]
}, class Plan {
name: blowdart-monthly-notrial
prettyName: blowdart-monthly-notrial
billingPeriod: MONTHLY
phases: [class Phase {
type: EVERGREEN
prices: [class Price {
currency: USD
value: 29.95
}, class Price {
currency: EUR
value: 29.95
}, class Price {
currency: GBP
value: 29.95
}]
fixedPrices: []
duration: class Duration {
unit: UNLIMITED
number: -1
}
usages: []
}]
}, class Plan {
name: blowdart-monthly-trial
prettyName: blowdart-monthly-trial
billingPeriod: MONTHLY
phases: [class Phase {
type: TRIAL
prices: []
fixedPrices: []
duration: class Duration {
unit: DAYS
number: 30
}
usages: []
}, class Phase {
type: EVERGREEN
prices: [class Price {
currency: USD
value: 29.95
}, class Price {
currency: EUR
value: 29.95
}, class Price {
currency: GBP
value: 29.95
}]
fixedPrices: []
duration: class Duration {
unit: UNLIMITED
number: -1
}
usages: []
}]
}]
included: []
available: []
}, class Product {
type: ADD_ON
name: Extra-Ammo
prettyName: Extra-Ammo
plans: [class Plan {
name: extra-ammo-monthly
prettyName: extra-ammo-monthly
billingPeriod: MONTHLY
phases: [class Phase {
type: EVERGREEN
prices: [class Price {
currency: USD
value: 999.95
}, class Price {
currency: EUR
value: 499.95
}, class Price {
currency: GBP
value: 999.95
}]
fixedPrices: []
duration: class Duration {
unit: UNLIMITED
number: -1
}
usages: []
}]
}]
included: []
available: []
}, class Product {
type: BASE
name: Shotgun
prettyName: Shotgun
plans: [class Plan {
name: shotgun-annual
prettyName: shotgun-annual
billingPeriod: ANNUAL
phases: [class Phase {
type: TRIAL
prices: []
fixedPrices: []
duration: class Duration {
unit: DAYS
number: 30
}
usages: []
}, class Phase {
type: EVERGREEN
prices: [class Price {
currency: USD
value: 2399.95
}, class Price {
currency: EUR
value: 1499.95
}, class Price {
currency: GBP
value: 1699.95
}]
fixedPrices: []
duration: class Duration {
unit: UNLIMITED
number: -1
}
usages: []
}]
}, class Plan {
name: shotgun-annual-gunclub-discount
prettyName: shotgun-annual-gunclub-discount
billingPeriod: ANNUAL
phases: [class Phase {
type: TRIAL
prices: []
fixedPrices: []
duration: class Duration {
unit: DAYS
number: 30
}
usages: []
}, class Phase {
type: DISCOUNT
prices: [class Price {
currency: USD
value: 19.95
}, class Price {
currency: EUR
value: 49.95
}, class Price {
currency: GBP
value: 69.95
}]
fixedPrices: []
duration: class Duration {
unit: MONTHS
number: 6
}
usages: []
}, class Phase {
type: EVERGREEN
prices: [class Price {
currency: USD
value: 2399.95
}, class Price {
currency: EUR
value: 1499.95
}, class Price {
currency: GBP
value: 1699.95
}]
fixedPrices: []
duration: class Duration {
unit: UNLIMITED
number: -1
}
usages: []
}]
}, class Plan {
name: shotgun-monthly
prettyName: Shotgun Monthly
billingPeriod: MONTHLY
phases: [class Phase {
type: TRIAL
prices: []
fixedPrices: []
duration: class Duration {
unit: DAYS
number: 30
}
usages: []
}, class Phase {
type: EVERGREEN
prices: [class Price {
currency: USD
value: 249.95
}, class Price {
currency: EUR
value: 149.95
}, class Price {
currency: GBP
value: 169.95
}]
fixedPrices: []
duration: class Duration {
unit: UNLIMITED
number: -1
}
usages: []
}]
}]
included: [Cleaning]
available: [Bullets, Holster, Laser-Scope, Telescopic-Scope]
}, class Product {
type: ADD_ON
name: Cleaning
prettyName: Cleaning
plans: [class Plan {
name: cleaning-monthly
prettyName: cleaning-monthly
billingPeriod: MONTHLY
phases: [class Phase {
type: EVERGREEN
prices: [class Price {
currency: USD
value: 2.95
}, class Price {
currency: EUR
value: 1.95
}, class Price {
currency: GBP
value: 0.95
}]
fixedPrices: []
duration: class Duration {
unit: UNLIMITED
number: -1
}
usages: []
}]
}]
included: []
available: []
}, class Product {
type: ADD_ON
name: Laser-Scope
prettyName: Laser-Scope
plans: [class Plan {
name: laser-scope-monthly
prettyName: laser-scope-monthly
billingPeriod: MONTHLY
phases: [class Phase {
type: DISCOUNT
prices: [class Price {
currency: USD
value: 999.95
}, class Price {
currency: EUR
value: 499.95
}, class Price {
currency: GBP
value: 999.95
}]
fixedPrices: []
duration: class Duration {
unit: MONTHS
number: 1
}
usages: []
}, class Phase {
type: EVERGREEN
prices: [class Price {
currency: USD
value: 1999.95
}, class Price {
currency: EUR
value: 1499.95
}, class Price {
currency: GBP
value: 1999.95
}]
fixedPrices: []
duration: class Duration {
unit: UNLIMITED
number: -1
}
usages: []
}]
}]
included: []
available: []
}, class Product {
type: STANDALONE
name: Knife
prettyName: Knife
plans: [class Plan {
name: knife-monthly-notrial
prettyName: knife-monthly-notrial
billingPeriod: MONTHLY
phases: [class Phase {
type: EVERGREEN
prices: [class Price {
currency: USD
value: 29.95
}, class Price {
currency: EUR
value: 29.95
}, class Price {
currency: GBP
value: 29.95
}]
fixedPrices: []
duration: class Duration {
unit: UNLIMITED
number: -1
}
usages: []
}]
}]
included: []
available: []
}, class Product {
type: BASE
name: Pistol
prettyName: Pistol
plans: [class Plan {
name: pistol-annual
prettyName: pistol-annual
billingPeriod: ANNUAL
phases: [class Phase {
type: TRIAL
prices: []
fixedPrices: []
duration: class Duration {
unit: DAYS
number: 30
}
usages: []
}, class Phase {
type: EVERGREEN
prices: [class Price {
currency: USD
value: 199.95
}, class Price {
currency: EUR
value: 199.95
}, class Price {
currency: GBP
value: 199.95
}]
fixedPrices: []
duration: class Duration {
unit: UNLIMITED
number: -1
}
usages: []
}]
}, class Plan {
name: pistol-annual-gunclub-discount
prettyName: pistol-annual-gunclub-discount
billingPeriod: ANNUAL
phases: [class Phase {
type: TRIAL
prices: []
fixedPrices: []
duration: class Duration {
unit: DAYS
number: 30
}
usages: []
}, class Phase {
type: DISCOUNT
prices: [class Price {
currency: USD
value: 9.95
}, class Price {
currency: EUR
value: 9.95
}, class Price {
currency: GBP
value: 9.95
}]
fixedPrices: []
duration: class Duration {
unit: MONTHS
number: 6
}
usages: []
}, class Phase {
type: EVERGREEN
prices: [class Price {
currency: USD
value: 199.95
}, class Price {
currency: EUR
value: 199.95
}, class Price {
currency: GBP
value: 199.95
}]
fixedPrices: []
duration: class Duration {
unit: UNLIMITED
number: -1
}
usages: []
}]
}, class Plan {
name: pistol-annual-gunclub-discount-notrial
prettyName: pistol-annual-gunclub-discount-notrial
billingPeriod: ANNUAL
phases: [class Phase {
type: DISCOUNT
prices: [class Price {
currency: USD
value: 9.95
}, class Price {
currency: EUR
value: 9.95
}, class Price {
currency: GBP
value: 9.95
}]
fixedPrices: []
duration: class Duration {
unit: MONTHS
number: 6
}
usages: []
}, class Phase {
type: EVERGREEN
prices: [class Price {
currency: USD
value: 199.95
}, class Price {
currency: EUR
value: 199.95
}, class Price {
currency: GBP
value: 199.95
}]
fixedPrices: []
duration: class Duration {
unit: UNLIMITED
number: -1
}
usages: []
}]
}, class Plan {
name: pistol-monthly
prettyName: pistol-monthly
billingPeriod: MONTHLY
phases: [class Phase {
type: TRIAL
prices: []
fixedPrices: []
duration: class Duration {
unit: DAYS
number: 30
}
usages: []
}, class Phase {
type: EVERGREEN
prices: [class Price {
currency: GBP
value: 29.95
}, class Price {
currency: EUR
value: 29.95
}, class Price {
currency: USD
value: 29.95
}]
fixedPrices: []
duration: class Duration {
unit: UNLIMITED
number: -1
}
usages: []
}]
}, class Plan {
name: pistol-monthly-fixedterm
prettyName: pistol-monthly-fixedterm
billingPeriod: MONTHLY
phases: [class Phase {
type: TRIAL
prices: []
fixedPrices: []
duration: class Duration {
unit: DAYS
number: 30
}
usages: []
}, class Phase {
type: FIXEDTERM
prices: [class Price {
currency: GBP
value: 29.95
}, class Price {
currency: EUR
value: 29.95
}, class Price {
currency: USD
value: 29.95
}]
fixedPrices: []
duration: class Duration {
unit: MONTHS
number: 12
}
usages: []
}]
}, class Plan {
name: pistol-monthly-notrial
prettyName: pistol-monthly-notrial
billingPeriod: MONTHLY
phases: [class Phase {
type: EVERGREEN
prices: [class Price {
currency: USD
value: 19.95
}, class Price {
currency: EUR
value: 19.95
}, class Price {
currency: GBP
value: 19.95
}]
fixedPrices: []
duration: class Duration {
unit: UNLIMITED
number: -1
}
usages: []
}]
}, class Plan {
name: pistol-quarterly
prettyName: pistol-quarterly
billingPeriod: QUARTERLY
phases: [class Phase {
type: TRIAL
prices: []
fixedPrices: []
duration: class Duration {
unit: DAYS
number: 30
}
usages: []
}, class Phase {
type: EVERGREEN
prices: [class Price {
currency: GBP
value: 69.95
}, class Price {
currency: EUR
value: 69.95
}, class Price {
currency: USD
value: 69.95
}]
fixedPrices: []
duration: class Duration {
unit: UNLIMITED
number: -1
}
usages: []
}]
}, class Plan {
name: pistol-thirty-days
prettyName: pistol-thirty-days
billingPeriod: THIRTY_DAYS
phases: [class Phase {
type: TRIAL
prices: []
fixedPrices: []
duration: class Duration {
unit: DAYS
number: 30
}
usages: []
}, class Phase {
type: EVERGREEN
prices: [class Price {
currency: GBP
value: 29.95
}, class Price {
currency: EUR
value: 29.95
}, class Price {
currency: USD
value: 29.95
}]
fixedPrices: []
duration: class Duration {
unit: UNLIMITED
number: -1
}
usages: []
}]
}, class Plan {
name: pistol-weekly
prettyName: pistol-weekly
billingPeriod: WEEKLY
phases: [class Phase {
type: TRIAL
prices: []
fixedPrices: []
duration: class Duration {
unit: DAYS
number: 30
}
usages: []
}, class Phase {
type: EVERGREEN
prices: [class Price {
currency: GBP
value: 29.95
}, class Price {
currency: EUR
value: 29.95
}, class Price {
currency: USD
value: 29.95
}]
fixedPrices: []
duration: class Duration {
unit: UNLIMITED
number: -1
}
usages: []
}]
}]
included: []
available: [Bullets, Cleaning, Refurbish-Maintenance]
}, class Product {
type: ADD_ON
name: Bullets
prettyName: Bullets
plans: [class Plan {
name: bullets-usage-in-arrear
prettyName: Bullet Monthly Plan
billingPeriod: NO_BILLING_PERIOD
phases: [class Phase {
type: EVERGREEN
prices: []
fixedPrices: []
duration: class Duration {
unit: UNLIMITED
number: -1
}
usages: [class Usage {
billingPeriod: MONTHLY
tiers: [class Tier {
limits: []
fixedPrice: []
recurringPrice: []
blocks: [class TieredBlock {
unit: bullets
size: 100.0
max: 10.0
prices: [class Price {
currency: USD
value: 2.95
}, class Price {
currency: EUR
value: 1.95
}, class Price {
currency: GBP
value: 0.95
}]
}]
}, class Tier {
limits: []
fixedPrice: []
recurringPrice: []
blocks: [class TieredBlock {
unit: bullets
size: 1000.0
max: 100.0
prices: [class Price {
currency: USD
value: 5.95
}, class Price {
currency: EUR
value: 4.95
}, class Price {
currency: GBP
value: 3.95
}]
}]
}]
}]
}]
}]
included: []
available: []
}, class Product {
type: ADD_ON
name: Telescopic-Scope
prettyName: Telescopic-Scope
plans: [class Plan {
name: telescopic-scope-monthly
prettyName: telescopic-scope-monthly
billingPeriod: MONTHLY
phases: [class Phase {
type: DISCOUNT
prices: [class Price {
currency: USD
value: 399.95
}, class Price {
currency: EUR
value: 299.95
}, class Price {
currency: GBP
value: 399.95
}]
fixedPrices: []
duration: class Duration {
unit: MONTHS
number: 1
}
usages: []
}, class Phase {
type: EVERGREEN
prices: [class Price {
currency: USD
value: 999.95
}, class Price {
currency: EUR
value: 499.95
}, class Price {
currency: GBP
value: 999.95
}]
fixedPrices: []
duration: class Duration {
unit: UNLIMITED
number: -1
}
usages: []
}]
}]
included: []
available: []
}]
priceLists: [class PriceList {
name: DEFAULT
plans: [assault-rifle-annual, assault-rifle-monthly, blowdart-monthly, bullets-usage-in-arrear, cleaning-monthly, extra-ammo-monthly, holster-monthly-regular, holster-monthly-special, laser-scope-monthly, pistol-annual, pistol-monthly, pistol-quarterly, pistol-thirty-days, pistol-weekly, refurbish-maintenance, shotgun-annual, shotgun-monthly, telescopic-scope-monthly, trebuchet-usage-in-arrear]
}, class PriceList {
name: gunclubDiscount
plans: [assault-rifle-annual-gunclub-discount, pistol-annual-gunclub-discount, shotgun-annual-gunclub-discount]
}, class PriceList {
name: gunclubDiscountNoTrial
plans: [pistol-annual-gunclub-discount-notrial]
}, class PriceList {
name: rescue
plans: [assault-rifle-annual-rescue]
}, class PriceList {
name: fixedTerm
plans: [pistol-monthly-fixedterm]
}, class PriceList {
name: notrial
plans: [blowdart-monthly-notrial, knife-monthly-notrial, pistol-monthly-notrial]
}, class PriceList {
name: trial
plans: [blowdart-monthly-trial]
}]
}
[
{
"name":"Movies",
"effectiveDate":"2013-02-08T00:00:00.000+0000",
"currencies":[
"USD"
],
"units":[
],
"products":[
{
"type":"BASE",
"name":"Basic",
"prettyName":"Basic",
"plans":[
{
"name":"basic-monthly",
"prettyName":"basic-monthly",
"billingPeriod":"MONTHLY",
"phases":[
{
"type":"EVERGREEN",
"prices":[
{
"currency":"USD",
"value":1000.0
}
],
"fixedPrices":[
],
"duration":{
"unit":"UNLIMITED",
"number":-1
},
"usages":[
]
}
]
}
],
"included":[
],
"available":[
]
}
],
"priceLists":[
{
"name":"DEFAULT",
"plans":[
"basic-monthly"
]
}
]
}
]
[{'currencies': ['USD', 'GBP'],
'effective_date': datetime.datetime(2013, 2, 8, 0, 0, tzinfo=tzutc()),
'name': 'SpyCarBasic',
'price_lists': [{'name': 'DEFAULT',
'plans': ['sports-monthly',
'standard-monthly',
'super-monthly']}],
'products': [{'available': [],
'included': [],
'name': 'Super',
'plans': [{'billing_period': 'MONTHLY',
'name': 'super-monthly',
'phases': [{'duration': {'number': 30,
'unit': 'DAYS'},
'fixed_prices': [],
'prices': [],
'type': 'TRIAL',
'usages': []},
{'duration': {'number': -1,
'unit': 'UNLIMITED'},
'fixed_prices': [],
'prices': [{'currency': 'GBP',
'value': 750.0},
{'currency': 'USD',
'value': 1000.0}],
'type': 'EVERGREEN',
'usages': []}],
'pretty_name': 'super-monthly'}],
'pretty_name': 'Super',
'type': 'BASE'},
{'available': [],
'included': [],
'name': 'Standard',
'plans': [{'billing_period': 'MONTHLY',
'name': 'standard-monthly',
'phases': [{'duration': {'number': 30,
'unit': 'DAYS'},
'fixed_prices': [],
'prices': [],
'type': 'TRIAL',
'usages': []},
{'duration': {'number': -1,
'unit': 'UNLIMITED'},
'fixed_prices': [],
'prices': [{'currency': 'GBP',
'value': 75.0},
{'currency': 'USD',
'value': 100.0}],
'type': 'EVERGREEN',
'usages': []}],
'pretty_name': 'standard-monthly'}],
'pretty_name': 'Standard',
'type': 'BASE'},
{'available': [],
'included': [],
'name': 'Sports',
'plans': [{'billing_period': 'MONTHLY',
'name': 'sports-monthly',
'phases': [{'duration': {'number': 30,
'unit': 'DAYS'},
'fixed_prices': [],
'prices': [],
'type': 'TRIAL',
'usages': []},
{'duration': {'number': -1,
'unit': 'UNLIMITED'},
'fixed_prices': [],
'prices': [{'currency': 'GBP',
'value': 375.0},
{'currency': 'USD',
'value': 500.0}],
'type': 'EVERGREEN',
'usages': []}],
'pretty_name': 'sports-monthly'}],
'pretty_name': 'Sports',
'type': 'BASE'}],
'units': []}]
Query Parameters
Name | Type | Required | Default | Description |
---|---|---|---|---|
requestedDate | string | false | current date | requested date |
Response
if successful, returns a status code of 200 and the full catalog for the requested date in JSON format.
Retrieve a list of catalog versions
Return a list of the effective dates for all available catalogs versions for this tenant.
HTTP Request
GET http://127.0.0.1:8080/1.0/kb/catalog/versions
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/catalog/versions"
import org.killbill.billing.client.api.gen.CatalogApi;
protected CatalogApi catalogApi;
UUID accountId = null;
List<DateTime> versions = catalogApi.getCatalogVersions(accountId, requestOptions);
KillBillClient::Model::Catalog.get_tenant_catalog_versions(options)
catalogApi = killbill.api.CatalogApi()
catalogApi.get_catalog_versions(api_key, api_secret)
Example Response:
# Subset of headers returned when specifying -v curl option
< HTTP/1.1 200 OK
< Content-Type: application/json
[
"2013-02-08T00:00:00.000Z"
]
2013-02-08T00:00:00.000Z
["2013-02-08T00:00:00.000Z"]
[datetime.datetime(2013, 2, 8, 0, 0, tzinfo=tzutc())]
Query Parameters
None.
Response
If successful, returns a status code of 200 and a comma-separated list of ISO date strings giving the effective date for each available catalog version.
Retrieve available base plans
Returns a list of available base products and associated plans. Each object returned specifies a product
, a priceList
, a plan
selected from the pricelist
, and pricing information for the final phase of the plan.
HTTP Request
GET http://127.0.0.1:8080/1.0/kb/catalog/availableBasePlans
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/catalog/availableBasePlans"
import org.killbill.billing.client.api.gen.CatalogApi;
protected CatalogApi catalogApi;
UUID accountId = null;
List<PlanDetail> basePlans = catalogApi.getAvailableBasePlans(accountId, requestOptions);
KillBillClient::Model::Catalog.available_base_plans(options)
catalogApi = killbill.api.CatalogApi()
catalogApi.get_available_base_plans(api_key, api_secret)
Example Response:
# Subset of headers returned when specifying -v curl option
< HTTP/1.1 200 OK
< Content-Type: application/json
[
{
"product": "Sports",
"plan": "sports-monthly",
"priceList": "DEFAULT",
"finalPhaseBillingPeriod": "MONTHLY",
"finalPhaseRecurringPrice": [
{
"currency": "GBP",
"value": 375
},
{
"currency": "USD",
"value": 500
}
]
},
{
"product": "Standard",
"plan": "standard-monthly",
"priceList": "DEFAULT",
"finalPhaseBillingPeriod": "MONTHLY",
"finalPhaseRecurringPrice": [
{
"currency": "GBP",
"value": 75
},
{
"currency": "USD",
"value": 100
}
]
}
]
//First element of the list
class PlanDetail {
product: Assault-Rifle
plan: assault-rifle-annual
priceList: DEFAULT
finalPhaseBillingPeriod: ANNUAL
finalPhaseRecurringPrice: [class Price {
currency: USD
value: 5999.95
}, class Price {
currency: EUR
value: 3499.95
}, class Price {
currency: GBP
value: 3999.95
}]
}
[
{
"product":"Basic",
"plan":"basic-annual",
"finalPhaseBillingPeriod":"ANNUAL",
"priceList":"DEFAULT",
"finalPhaseRecurringPrice":[
{
"currency":"USD",
"value":10000.0
}
]
},
{
"product":"Basic",
"plan":"basic-monthly",
"finalPhaseBillingPeriod":"MONTHLY",
"priceList":"DEFAULT",
"finalPhaseRecurringPrice":[
{
"currency":"USD",
"value":1000.0
}
]
}
]
[{'final_phase_billing_period': 'MONTHLY',
'final_phase_recurring_price': [{'currency': 'GBP', 'value': 375.0},
{'currency': 'USD', 'value': 500.0}],
'plan': 'sports-monthly',
'price_list': 'DEFAULT',
'product': 'Sports'}, {'final_phase_billing_period': 'MONTHLY',
'final_phase_recurring_price': [{'currency': 'GBP', 'value': 75.0},
{'currency': 'USD', 'value': 100.0}],
'plan': 'standard-monthly',
'price_list': 'DEFAULT',
'product': 'Standard'}, {'final_phase_billing_period': 'MONTHLY',
'final_phase_recurring_price': [{'currency': 'GBP', 'value': 750.0},
{'currency': 'USD', 'value': 1000.0}],
'plan': 'super-monthly',
'price_list': 'DEFAULT',
'product': 'Super'}]
Query Parameters
None.
Response
If successful, returns a status code of 200 and a list of objects representing the available base products and plans.
Retrieve available add-ons for a given product
Returns a list of available add-on products, if any, for a specified base product, and for a specified price list or all price lists. Each object returned specifies a product
, a priceList
, a plan
selected from the pricelist
, and pricing information for the final phase of the plan.
HTTP Request
GET http://127.0.0.1:8080/1.0/kb/catalog/availableAddons
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/catalog/availableAddons"
import org.killbill.billing.client.api.gen.CatalogApi;
protected CatalogApi catalogApi;
String baseProductName = "Bullets";
String priceListName = null;
UUID accountId = null;
List<PlanDetail> availableAddons = catalogApi.getAvailableAddons(baseProductName,
priceListName,
accountId,
requestOptions);
base_product_name = 'Basic'
KillBillClient::Model::Catalog.available_addons(base_product_name,
options)
catalogApi = killbill.api.CatalogApi()
catalogApi.get_available_addons(api_key,
api_secret,
base_product_name='Basic')
Example Response:
# Subset of headers returned when specifying -v curl option
< HTTP/1.1 200 OK
< Content-Type: application/json
[
{
"product":"Basic",
"plan":"basic-annual",
"finalPhaseBillingPeriod":"ANNUAL",
"priceList":"DEFAULT",
"finalPhaseRecurringPrice":[
{
"currency":"USD",
"value":10000.0
}
]
}
]
//First element of the list
class PlanDetail {
product: Bullets
plan: bullets-usage-in-arrear
priceList: DEFAULT
finalPhaseBillingPeriod: NO_BILLING_PERIOD
finalPhaseRecurringPrice: []
}
[
{
"product":"Basic",
"plan":"basic-annual",
"finalPhaseBillingPeriod":"ANNUAL",
"priceList":"DEFAULT",
"finalPhaseRecurringPrice":[
{
"currency":"USD",
"value":10000.0
}
]
}
]
[{'product': 'Basic',
'plan': 'basic-annual',
'final_phase_billing_period': 'ANNUAL',
'price_list': 'DEFAULT',
'final_phase_recurring_price':[{'currency': 'USD',
'value': 10000.0}]
}]
Query Parameters
Name | Type | Required | Default | Description |
---|---|---|---|---|
baseProductName | string | true | none | base product name |
priceListName | string | false | all price lists | price list name |
Response
If successful, returns a status code of 200 and a list of objects representing available add-on products.
Delete all versions of a per tenant catalog
Delete all per-tenant catalog versions. The tenant reverts to the system default catalog.
HTTP Request
DELETE http://127.0.0.1:8080/1.0/kb/catalog
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/catalog"
import org.killbill.billing.client.api.gen.CatalogApi;
protected CatalogApi catalogApi;
catalogApi.deleteCatalog(requestOptions);
KillBillClient::Model::Catalog.delete_catalog(user,
reason,
comment,
options)
catalogApi = killbill.api.CatalogApi()
catalogApi.delete_catalog(created_by, api_key, api_secret)
Example Response:
# Subset of headers returned when specifying -v curl option
< HTTP/1.1 204 No Content
no content
no content
no content
Query Parameters
None.
Response
If successful, returns a a status code of 204 and an empty body.
Validate a catalog XML
This endpoint validates an XML catalog.
Following are some of the errors that can be detected via this endpoint:
- Catalog name does not match the name of the existing catalog
- A catalog with the particular effectiveDate already exists
- An EVERGREEN phase does not have duration as UNLIMITED
HTTP Request
POST http://127.0.0.1:8080/1.0/kb/catalog/xml/validate
Example Request:
curl -v \
-X POST \
-u admin:password \
-H "X-Killbill-ApiKey: bob" \
-H "X-Killbill-ApiSecret: lazar" \
-H "Content-Type: text/xml" \
-H "Accept: application/json" \
-H "X-Killbill-CreatedBy: demo" \
-H "X-Killbill-Reason: demo" \
-H "X-Killbill-Comment: demo" \
-d @<path_to_catalog_xml> \
"http://127.0.0.1:8080/1.0/kb/catalog/xml/validate"
import org.killbill.billing.client.api.gen.CatalogApi;
protected CatalogApi catalogApi;
String catalogPath = "in-advance-arrear.xml";
String body = getResourceBodyString(catalogPath);
CatalogValidation validation = catalogApi.validateCatalogXml(body, requestOptions);
List<CatalogValidationError> errors = validation.getCatalogValidationErrors();
TODO
TODO
Example Response:
# Subset of headers returned when specifying -v curl option
< HTTP/1.1 200 Created
< Content-Type: application/json
{
"catalogValidationErrors": [
{
"errorDescription": "Catalog name 'ExampleCatalog' is different from existing catalog name 'Firearms'"
}
]
}
[class CatalogValidationError {
errorDescription: Catalog name 'ExampleCatalog' is different from existing catalog name 'Firearms'
}]
no content
no content
Request Body
The complete catalog in XML format. Alternative, the path to the catalog XML file can also be specified.
Query Parameters
None.
Response
If successful, returns a status code of 200 and a CatalogValidation
object. If validation is successful and there are no validation errors, the CatalogValidation
object is empty, otherwise it contains a CatalogValidationError
List.
Subscription info
These endpoints return information concerning a particular subscription. They select from the catalog only the items (such as plan, phase, or products) that currently apply to the specified subscription.
Retrieve the phase for a given subscription and date
This API returns information about the current Phase
associated with a given subscription. The record returned includes the phase type and information about pricing, duration, and usage.
HTTP Request
GET http://127.0.0.1:8080/1.0/kb/catalog/phase
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/catalog/phase?subscriptionId=8ab101b6-15e8-433b-b4f7-f99eeaa56a77&requestedDate=2018-7-18"
TODO
requested_date = nil
KillBillClient::Model::Catalog.get_catalog_phase(subscription_id,
requested_date,
options)
catalogApi = killbill.api.CatalogApi()
catalogApi.get_phase_for_subscription_and_date(api_key,
api_secret,
subscription_id=subscription_id)
Example Response:
# Subset of headers returned when specifying -v curl option
< HTTP/1.1 200 OK
< Content-Type: application/json
{
"type": "TRIAL",
"prices": [],
"fixedPrices": [],
"duration": {
"unit": "DAYS",
"number": 30
},
"usages": []
}
TODO
{
"duration":{
"number":30,
"unit":"DAYS"
},
"fixed_prices":[
],
"prices":[
],
"type":"TRIAL",
"usages":[
]
}
{'duration': {'number': 30, 'unit': 'DAYS'},
'fixed_prices': [],
'prices': [],
'type': 'TRIAL',
'usages': []}
Query Parameters
Name | Type | Required | Default | Description |
---|---|---|---|---|
subscriptionId | string | true | none | subscription id |
requestedDate | string | false | current date | requested date |
Response
If successful, returns a status code of 200 and a record for the current phase.
Retrieve the plan for a given subscription and date
This API returns information about the current Plan
associated with a given subscription. The record returned includes the plan name and information for each phase of the plan.
HTTP Request
GET http://127.0.0.1:8080/1.0/kb/catalog/plan
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/catalog/plan?subscriptionId=8ab101b6-15e8-433b-b4f7-f99eeaa56a77&requestedDate=2018-7-18"
TODO
requested_date = nil
KillBillClient::Model::Catalog.get_catalog_plan(subscription_id,
requested_date,
options)
catalogApi = killbill.api.CatalogApi()
catalogApi.get_plan_for_subscription_and_date(api_key,
api_secret,
subscription_id=subscription_id)
Example Response:
{
"name": "standard-monthly",
"prettyName": "standard-monthly",
"billingPeriod": "MONTHLY",
"phases": [
{
"type": "TRIAL",
"prices": [],
"fixedPrices": [],
"duration": {
"unit": "DAYS",
"number": 30
},
"usages": []
},
{
"type": "EVERGREEN",
"prices": [
{
"currency": "GBP",
"value": 75
},
{
"currency": "USD",
"value": 100
}
],
"fixedPrices": [],
"duration": {
"unit": "UNLIMITED",
"number": -1
},
"usages": []
}
]
}
TODO
{
"billing_period":"MONTHLY",
"name":"standard-monthly",
"phases":[
{
"duration":{
"number":30,
"unit":"DAYS"
},
"fixed_prices":[
],
"prices":[
],
"type":"TRIAL",
"usages":[
]
},
{
"duration":{
"number":-1,
"unit":"UNLIMITED"
},
"fixed_prices":[
],
"prices":[
{
"currency":"GBP",
"value":75.0
},
{
"currency":"USD",
"value":100.0
}
],
"type":"EVERGREEN",
"usages":[
]
}
],
"pretty_name":"standard-monthly"
}
{'billing_period': 'MONTHLY',
'name': 'standard-monthly',
'phases': [{'duration': {'number': 30, 'unit': 'DAYS'},
'fixed_prices': [],
'prices': [],
'type': 'TRIAL',
'usages': []},
{'duration': {'number': -1, 'unit': 'UNLIMITED'},
'fixed_prices': [],
'prices': [{'currency': 'GBP', 'value': 75.0},
{'currency': 'USD', 'value': 100.0}],
'type': 'EVERGREEN',
'usages': []}],
'pretty_name': 'standard-monthly'}
Query Parameters
Name | Type | Required | Default | Description |
---|---|---|---|---|
subscriptionId | string | true | none | subscription id |
requestedDate | string | false | current date | requested date |
Response
If successful, returns a status code of 200 and a record for the plan for this subscription.
Retrieve the priceList for a given subscription and date
This API returns information about the current priceList
associated with a given subscription. The record returned includes the price list name and the list of plans on this list.
HTTP Request
GET http://127.0.0.1:8080/1.0/kb/catalog/priceList
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/catalog/priceList?subscriptionId=8ab101b6-15e8-433b-b4f7-f99eeaa56a77&requestedDate=2018-7-18"
TODO
requested_date = nil
KillBillClient::Model::Catalog.get_catalog_price_list(subscription_id,
requested_date,
options)
catalogApi = killbill.api.CatalogApi()
catalogApi.get_price_list_for_subscription_and_date(api_key,
api_secret,
subscription_id=subscription_id)
Example Response:
{
"name": "DEFAULT",
"plans": [
"sports-monthly",
"standard-monthly",
"super-monthly"
]
}
TODO
{
"name":"DEFAULT",
"plans":[
"sports-monthly",
"standard-monthly",
"super-monthly"
]
}
{'name': 'DEFAULT',
'plans': ['sports-monthly', 'standard-monthly', 'super-monthly']}
Query Parameters
Name | Type | Required | Default | Description |
---|---|---|---|---|
subscriptionId | string | true | none | subscription id |
requestedDate | string | false | current date | requested date |
Response
If successful, returns a status code of 200 and a record for the price list for this subscription.
Retrieve product for a given subscription and date
This API returns information about the product
associated with a given subscription. The record returned includes the product names, available plans, items included, and available add-ons.
HTTP Request
GET http://127.0.0.1:8080/1.0/kb/catalog/product
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/catalog/product?subscriptionId=8ab101b6-15e8-433b-b4f7-f99eeaa56a77&requestedDate=2018-7-18"
TODO
requested_date = nil
KillBillClient::Model::Catalog.get_catalog_product(subscription_id,
requested_date,
options)
catalogApi = killbill.api.CatalogApi()
catalogApi.get_product_for_subscription_and_date(api_key,
api_secret,
subscription_id=subscription_id)
Example Response:
# Subset of headers returned when specifying -v curl option
< HTTP/1.1 200 OK
< Content-Type: application/json
{
"type": "BASE",
"name": "Standard",
"prettyName": "Standard",
"plans": [],
"included": [],
"available": []
}
TODO
{
"available":[
],
"included":[
],
"name":"Standard",
"plans":[
],
"pretty_name":"Standard",
"type":"BASE"
}
{'available': [],
'included': [],
'name': 'Standard',
'plans': [],
'pretty_name': 'Standard',
'type': 'BASE'}
Query Parameters
Name | Type | Required | Default | Description |
---|---|---|---|---|
subscriptionId | string | true | none | subscription id |
requestedDate | string | false | current date | requested date |
Response
If successful, returns a status code of 200 and a record for the product for this subscription.
Simple Plan
We provide a more basic level of APIs as a quick way to add a Plan
into an existing version of the catalog.
The intent is mostly to help getting started with Kill Bill by abstracting away more complex topics such as alignements, rules, ...
The functionality is exposed on our admin UI (KAUI) to provide a simple graphical way to configure a simple catalog and get started quickly.
One can directly use our Simple Plan API to add new Plans
without the need to create an initial catalog version: If there is no
existing catalog version for the tenant, the system will create such an initial version when the first plan is added; otherwise, the
system will use the existing active catalog version to add the new plan (but it will not create a new catalog version).
Note that because the Simple Plan API is just an abstraction on top of the more complex XML based APIs, one can start with such Simple Plan API, and then download the resulting XML, and edit such catalog by hand (to add entries, modify default rules, ...).
A simple plan has the following limitations:
- In-advance billing only
- Limited to one
RECURRING
phase and an optional $0TRIAL
phase - No suport for fixed price
Once a simple plan has been uploaded, one can retrieve the associated XML, edit it to configure additional aspects, and then upload a new version of this catalog. So, this functionality can also be a stepping stone to a full catalog configuration.
Add a simple plan
Add a (simple) Plan into the current version of the Catalog associated with the tenant.
HTTP Request
POST http://127.0.0.1:8080/1.0/kb/catalog/simplePlan
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 '{ "planId": "basic-annual", "productName": "Basic", "productCategory": "BASE", "currency": "USD", "amount": 1000, "billingPeriod": "ANNUAL", "trialLength": 0, "trialTimeUnit": "UNLIMITED"}' \
"http://localhost:8080/1.0/kb/catalog/simplePlan"
import org.killbill.billing.client.api.gen.CatalogApi;
protected CatalogApi catalogApi;
String planId = "foo-monthly";
String productName = "Foo";
Integer trialLength = 0;
SimplePlan body = new SimplePlan(planId,
productName,
ProductCategory.BASE,
Currency.USD,
BigDecimal.TEN,
BillingPeriod.MONTHLY,
trialLength,
TimeUnit.UNLIMITED,
Collections.emptyList())
catalogApi.addSimplePlan(body, requestOptions);
simple_plan = KillBillClient::Model::SimplePlanAttributes.new
simple_plan.plan_id = 'basic-annual'
simple_plan.product_name = 'Basic'
simple_plan.product_category = 'BASE'
simple_plan.currency = 'USD'
simple_plan.amount = 10000.00
simple_plan.billing_period = 'ANNUAL'
simple_plan.trial_length = 0
simple_plan.trial_time_unit = 'UNLIMITED'
KillBillClient::Model::Catalog.add_tenant_catalog_simple_plan(simple_plan,
user,
reason,
comment,
options)
catalogApi = killbill.api.CatalogApi()
body = SimplePlan(plan_id='basic-annual',
product_name='Basic',
product_category='BASE',
currency='USD',
amount=10000.00,
billing_period='ANNUAL',
trial_length=0,
trial_time_unit='UNLIMITED')
catalogApi.add_simple_plan(body, created_by, api_key, api_secret)
Example Response:
# Subset of headers returned when specifying -v curl option
< HTTP/1.1 201 Created
< Location: http://localhost:8080/1.0/kb/catalog
< Content-Type: application/json
< Content-Length: 0
TODO
no content
no content
Request Body
Provides the content for the plan in JSON form. This should be very simple. Note that the "planId" becomes the planName
attribute. For example:
{
"planId": "newplan",
"productName": "myitem",
"productCategory": "BASE",
"currency": "USD",
"amount": 0,
"billingPeriod": "DAILY",
"trialLength": 0,
"trialTimeUnit": "DAYS",
"availableBaseProducts": []
}
Query Parameters
None.
Response
If successful, returns a status code of 201 and an empty body.
Account
Each of your customers is identified by an account. The information for an account is contained in an account resource object. The endpoints in this group manage the account resource and the information it contains.
Account Resource
An Account
resource represents a customer. This is the top level per-customer resource. All other per-customer data, such as bundles, subscriptions, invoices and payments, will be linked to this resource. An account resource may contain Personally Identifiable Information (PII) for the customer such as name, address, email, etc. A large number of endpoints are available to manage not only purely account related information -- e.g name
-- but other per-account data as well.
The attributes contained in the account resource are the following:
Name | Type | Generated by | Description |
---|---|---|---|
accountId | string | system | UUID for this account |
externalKey | string | user | Optional external key provided by the client |
referenceTime | string | system | ISO date and time this account was created |
parentAccountId | string | user | UUID for the parent account, if any, if the hierarchical accounts (HA) model is used |
isPaymentDelegatedToParent | boolean | user | For the hierarchical model, indicates whether the parent account, if any, is handling payments for this account |
currency | string | user | Default currency for the customer |
billCycleDayLocal | integer | system or user | Default day of the month to bill customers for subscriptions with an ACCOUNT billing alignment and a billing period that is a multiple of one month. |
paymentMethodId | string | user | UUID for the default payment method used by the system to make recurring payments |
name | string | user | Name of the account |
firstNameLength | integer | user | Length of the first name (first part of name) |
company | string | user | Customer's company name |
address1 | string | user | Address line 1 |
address2 | string | user | Address line 2 |
city | string | user | Customer's city |
state | string | user | Customer's state, if any |
postalCode | string | user | Customer's postal code, if any |
country | string | user | Customer's ISO country identifier |
locale | string | user | ISO locale code for customer language |
timeZone | string | user | Descriptor for the customer's time zone. Used by the system to make any required transformation from DateTime to LocalDate |
phone | string | user | Phone contact number to reach the customer |
string | user | Primary email to reach the customer | |
notes | string | user | Additonal notes about the customer, usually set by the customer service department |
isMigrated | boolean | user | Indicates whether this account has been migrated from another system |
accountCBA | integer | system | Account credit, if any |
accountBalance | integer | system | Account balance, if any |
auditLogs | array | system | Array of audit log records for this account |
The name is usually the personal name of the account owner. We recommend that this be entered so that the first word is an acceptable short form for the complete name, such as "first name" in most English-speaking cultures. In this case the value firstNameLength enables your code to extract this part of the name for informal greetings. For information on name formats in various countries see Personal Names around the World by the W3C.
A list of valid timeZone strings is given at timezone strings.
For information about migrating accounts from a previous system see the Migration Guide.
Accounts
Create an Account
Create a new customer Account
.
HTTP Request
POST http://127.0.0.1:8080/1.0/kb/accounts
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 '{ "name": "John Doe", "email": "john@laposte.com", "currency": "USD"}' \
"http://127.0.0.1:8080/1.0/kb/accounts"
import org.killbill.billing.client.api.gen.AccountApi;
protected AccountApi accountApi;
Account body = new Account();
body.setName("John Doe");
body.setEmail("john@laposte.com");
body.setCurrency(Currency.USD);
Account result = accountApi.createAccount(body, requestOptions);
account = KillBillClient::Model::Account.new
account.name = "John Doe"
account.email = "john@laposte.com"
account.currency = "USD"
account.create(user, reason, comment, options)
accountApi = killbill.api.AccountApi()
created_by = 'example'
body = Account(name='John Doe',
email='john@laposte.com',
currency='USD')
accountApi.create_account(body,
created_by,
api_key,
api_secret)
{
"auditLogs":[],
"externalKey":"36c05a84-563b-4794-8958-772d93e677e1",
"accountId":"36c05a84-563b-4794-8958-772d93e677e1",
"referenceTime":
{
"year":2023,
"dayOfYear":67,
"equalNow":false,
"weekyear":2023,
"chronology":{
"zone":{
"ID":"UTC"
}
},
"weekOfWeekyear":10,
"secondOfMinute":16,
"millisOfDay":59476000,
"monthOfYear":3,
"dayOfWeek":3,
"beforeNow":true,
"minuteOfDay":991,
"dayOfMonth":8,
"era":1,
"zone":{
"ID":"UTC"
},
"yearOfCentury":23,
"hourOfDay":16,
"centuryOfEra":20,
"secondOfDay":59476,
"millis":1678293076000,
"yearOfEra":2023,
"minuteOfHour":31,
"millisOfSecond":0,
"afterNow":false
},
"paymentDelegatedToParent":false,
"name":"John Doe",
"timeZone":"UTC",
"currency":"USD",
"billCycleDayLocal":0,
"email":"john@laposte.com"
}
Request Body
The body of the request is a JSON string specifying any attributes of the resource that need to be assigned an initial value. No attributes are required. For any attributes omitted, the following defaults are generated:
Attribute | Default |
---|---|
accountId | System generated UUID |
externalKey | Copy of accountId |
billCycleDayLocal | 0 |
isPaymentDelegatedToParent | false |
referenceTime | ISO time-date code for the current time in the specified timezone |
timeZone | "UTC" |
all others | null |
All attributes are optional, so it is possible to quickly create a shell account. This account could be used for test purposes, so its attributes can be filled in later. This also ensures the initial account contains no PII. Note, however, that the currency
attribute must have a non-null value. This cannot be added later and is required for invoicing to work properly.
A few fields are not updatable; they can only be set once when creating the original Account
. These include externalKey
, currency
, timeZone
, and referenceTime
. In addition the billCycleDayLocal
can be updated but only once, that is one can create an Account
without specifying the billCycleDayLocal
and later update its value; this, in particular allows the system to update its value to a good default, that is one that will avoid leading prorations, when creating the first subscription.
The accountId
and audit logs are generated by the system and cannot be set or modified by the user.
In order to create an account as a child account, the parentAccountId
attribute needs to be specified with the id
of the parent account. Also, the isPaymentDelegatedToParent
attribute can be specified with a true/false value. A false
indicates that the child account will be responsible for paying its own invoices while a true
indicates that the parent account will be responsible for paying the child account invoices.
Query Parameters
none
Response
If successful, returns a 201 status code. In addition, a Location
header is returned giving the URL for the account object, including the generated accountId
.
Retrieve an Account by its ID
Retrieves the full resource object for an Account
using its accountId
.
HTTP Request
GET http://127.0.0.1:8080/1.0/kb/accounts/{accountId}
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/accounts/36c05a84-563b-4794-8958-772d93e677e1"
import org.killbill.billing.client.api.gen.AccountApi;
protected AccountApi accountApi;
UUID accountId = UUID.fromString("36c05a84-563b-4794-8958-772d93e677e1");
Boolean accountWithBalance = false; // Will not include account balance
Boolean accountWithBalanceAndCBA = false; // Will not include account balance and CBA info
Account result = accountApi.getAccount(accountId,
accountWithBalance,
accountWithBalanceAndCBA,
AuditLevel.NONE,
requestOptions);
account_id = "36c05a84-563b-4794-8958-772d93e677e1"
with_balance = false
with_balance_and_cba = false
account = KillBillClient::Model::Account.new
account.find_by_id(account_id,
with_balance,
with_balance_and_cba,
options)
accountApi = killbill.api.AccountApi()
account_id = '36c05a84-563b-4794-8958-772d93e677e1'
accountApi.get_account(account_id, api_key, api_secret)
Example Response:
{
"accountId": "36c05a84-563b-4794-8958-772d93e677e1",
"name": "John Doe",
"firstNameLength": null,
"externalKey": "36c05a84-563b-4794-8958-772d93e677e1",
"email": "john@laposte.com",
"billCycleDayLocal": 0,
"currency": "USD",
"parentAccountId": null,
"isPaymentDelegatedToParent": false,
"paymentMethodId": null,
"referenceTime": "2023-03-08T16:31:16.000Z",
"timeZone": "UTC",
"address1": null,
"address2": null,
"postalCode": null,
"company": null,
"city": null,
"state": null,
"country": null,
"locale": null,
"phone": null,
"notes": null,
"isMigrated": null,
"accountBalance": null,
"accountCBA": null,
"auditLogs": []
}
Query Parameters
Name | Type | Required | Default | Description |
---|---|---|---|---|
accountWithBalance | boolean | false | false | If true, returns accountBalance info |
accountWithBalanceAndCBA | boolean | false | false | If true, returns accountBalance and accountCBA info |
audit | string | false | "NONE" | Level of audit information to return: "NONE", "MINIMAL", or "FULL" |
Response
If successful, returns a status code of 200 and an account object in the response body.
Retrieve an Account by its external key
Retrieves the resource object for an Account
using its externalKey
as an identifier.
HTTP Request
GET http://127.0.0.1:8080/1.0/kb/accounts
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/accounts?externalKey=36c05a84-563b-4794-8958-772d93e677e1"
import org.killbill.billing.client.api.gen.AccountApi;
protected AccountApi accountApi;
String externalKey = "36c05a84-563b-4794-8958-772d93e677e1";
Boolean accountWithBalance = false; // Will not include account balance
Boolean accountWithBalanceAndCBA = false; // Will not include account balance and CBA info
Account result = accountApi.getAccountByKey(externalKey,
accountWithBalance,
accountWithBalanceAndCBA,
AuditLevel.NONE,
requestOptions);
external_key = '36c05a84-563b-4794-8958-772d93e677e1'
with_balance = false
with_balance_and_cba = false
account = KillBillClient::Model::Account.new
account.find_by_external_key(external_key,
with_balance,
with_balance_and_cba,
options)
accountApi = killbill.api.AccountApi()
external_key = '36c05a84-563b-4794-8958-772d93e677e1'
accountApi.get_account(external_key, api_key, api_secret)
Example Response:
{
"accountId": "36c05a84-563b-4794-8958-772d93e677e1",
"name": "John Doe",
"firstNameLength": null,
"externalKey": "36c05a84-563b-4794-8958-772d93e677e1",
"email": "john@laposte.com",
"billCycleDayLocal": 0,
"currency": "USD",
"parentAccountId": null,
"isPaymentDelegatedToParent": false,
"paymentMethodId": null,
"referenceTime": "2023-03-08T16:31:16.000Z",
"timeZone": "UTC",
"address1": null,
"address2": null,
"postalCode": null,
"company": null,
"city": null,
"state": null,
"country": null,
"locale": null,
"phone": null,
"notes": null,
"isMigrated": null,
"accountBalance": null,
"accountCBA": null,
"auditLogs": []
}
Query Parameters
Name | Type | Required | Default | Description |
---|---|---|---|---|
externalKey | string | true | none | External key to be used for retrieval |
accountWithBalance | boolean | false | false | If true, returns accountBalance info |
accountWithBalanceAndCBA | boolean | false | false | If true, returns accountBalance and accountCBA info |
audit | string | false | "NONE" | Level of audit information to return: "NONE", "MINIMAL", or "FULL" |
Response
If successful, returns a status code of 200 and an account object in the response body.
Update an Account
Updates selected attributes in an account object. Note that the following fields are not updatable; they can only be set once when creating the original Account
: externalKey
, currency
, timeZone
, and referenceTime
. In addition, the billCycleDayLocal
can be updated but only once, that is, one can create an Account
without specifying the billCycleDayLocal
and later update its value. This, allows the system to update its value to a good default, that is one that will avoid leading prorations, when creating the first subscription. Also, the audit logs cannot be changed.
The updates are passed in the request body, as an object that only needs to contain the attributes to be changed. Any attribute omitted from the request body will remain unchanged.
If the boolean query parameter treatNullAsReset is true
, any attribute specified as null
in the request will be set to null. If the parameter is false
, any attribute specified as null
in the request will remain unchanged.
HTTP Request
PUT http://127.0.0.1:8080/1.0/kb/accounts/{accountId}
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 '{ "name": "Another Name"}' \
"http://127.0.0.1:8080/1.0/kb/accounts/2ad52f53-85ae-408a-9879-32a7e59dd03d"
import org.killbill.billing.client.api.gen.AccountApi;
protected AccountApi accountApi;
UUID accountId = UUID.fromString("864c1418-e768-4cd5-a0db-67537144b685");
Account body = new Account();
body.setAccountId(accountId);
body.setName("Another Name");
Boolean treatNullAsReset = false; // any attribute with a null value in the request body will be unchanged
// If set to true, you will need to explicitly set the externalKey, currency and timezone fields to their original values, otherwise a KillBillClientException will occur.
accountApi.updateAccount(accountId,
body,
treatNullAsReset,
requestOptions);
account.name = 'Another Name'
treat_null_as_reset = true
account.update(treat_null_as_reset,
user,
reason,
comment,
options)
accountApi = killbill.api.AccountApi()
account_id = '07c0cef4-41c5-4606-b2cd-661332cdd41c'
created_by = 'example'
body = Account(name='Another Name')
accountApi.update_account(account_id,
body,
created_by,
api_key,
api_secret)
Example Response:
{
"accountId":"37e759ed-e769-4e81-9e39-afb75a33056d",
"name":"Another Name",
"externalKey":"1521656367-130272",
"email":"kill@bill.com",
"billCycleDayLocal":0,
"currency":"USD",
"isPaymentDelegatedToParent":false,
"timeZone":"UTC",
"address1":"7, yoyo road",
"address2":"Apt 5",
"postalCode":"94105",
"company":"Unemployed",
"city":"San Francisco",
"state":"California",
"country":"US",
"locale":"fr_FR",
"notes":"My notes",
"auditLogs":[]
}
Query Parameters
Name | Type | Required | Default | Description |
---|---|---|---|---|
treatNullAsReset | boolean | false | false | If true, any attribute with a null value in the request body will be set to null . If false, any attribute with a null value in the request body will be unchanged. |
Response
If successful, returns a status code of 204 and an empty body..
Close account
This endpoint can be used when no other state change will occur on this Account
to bring it to a stable state. Depending on the value of the query parameters it will potentially cancel all active subscriptions, write-off unpaid invoices, etc. This endpoint is not for account deletion. We provide no support to remove state through APIs; such deletion operations, if really needed, would have to happen at the database level and are not encouraged. They can be tricky to get right.
HTTP Request
DELETE http://127.0.0.1:8080/1.0/kb/accounts/{accountId}
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/accounts/8785164f-b5d7-4da1-9495-33f5105e8d80"
import org.killbill.billing.client.api.gen.AccountApi;
protected AccountApi accountApi;
UUID accountId = UUID.fromString("864c1418-e768-4cd5-a0db-67537144b685");
Boolean cancelAllSubscriptions = true; // Will cancel all subscriptions
Boolean writeOffUnpaidInvoices = true; // Will write off unpaid invoices
Boolean itemAdjustUnpaidInvoices = false; // Will not adjust unpaid invoices
Boolean removeFutureNotifications = true; // Will remove future notifications
accountApi.closeAccount(accountId,
cancelAllSubscriptions,
writeOffUnpaidInvoices,
itemAdjustUnpaidInvoices,
removeFutureNotifications,
requestOptions);
cancel_subscriptions = false
writeoff_unpaid_invoices = false
item_adjust_unpaid_invoices = false
account.close(cancel_subscriptions,
writeoff_unpaid_invoices,
item_adjust_unpaid_invoices,
user,
reason,
comment,
options)
accountApi = killbill.api.AccountApi()
account_id = '07c0cef4-41c5-4606-b2cd-661332cdd41c'
accountApi.close_account(account_id,
created_by,
api_key,
api_secret)
Example Response:
no content
Query Parameters
Name | Type | Required | Default | Description |
---|---|---|---|---|
cancelAllSubscriptions | boolean | false | false | If true, cancel all subscriptions |
writeOffUnpaidInvoices | boolean | false | false | If true, write off unpaid invoices |
itemAdjustUnpaidInvoices | boolean | false | false | If true, adjust unpaid invoices |
removeFutureNotifications | boolean | false | false | If true, remove future notifications |
Response
IF successful, returns a status code of 204 and an empty body.
List and Search
These endpoints allow you to list all accounts or to search for a specific account.
List accounts
Retrieve a list of all account records.
HTTP Request
GET http://127.0.0.1:8080/1.0/kb/accounts/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/accounts/pagination"
import org.killbill.billing.client.api.gen.AccountApi;
protected AccountApi accountApi;
Long offset = 0L;
Long limit = 1L;
Boolean accountWithBalance = false; // Will not include account balance
Boolean accountWithBalanceAndCBA = false; // Will not include account balance and CBA info
Accounts allAccounts = accountApi.getAccounts(offset,
limit,
accountWithBalance,
accountWithBalanceAndCBA,
AuditLevel.NONE,
requestOptions);
offset = 0
limit = 100
with_balance = false
with_balance_and_cba = false
account.find_in_batches(offset,
limit,
with_balance,
with_balance_and_cba,
options)
accountApi = killbill.api.AccountApi()
accountApi.get_accounts(api_key, api_secret)
Example Response:
{
"next": [
{
"auditLogs": [],
"externalKey": "e60a79de-0d4c-4aeb-82e9-7695fe393b81",
"accountId": "e60a79de-0d4c-4aeb-82e9-7695fe393b81",
"referenceTime": {
"year": 2023,
"dayOfYear": 65,
"equalNow": false,
"weekyear": 2023,
"chronology": {
"zone": {
"ID": "UTC"
}
},
"weekOfWeekyear": 10,
"secondOfMinute": 39,
"millisOfDay": 61959000,
"monthOfYear": 3,
"dayOfWeek": 1,
"beforeNow": true,
"minuteOfDay": 1032,
"dayOfMonth": 6,
"era": 1,
"zone": {
"ID": "UTC"
},
"yearOfCentury": 23,
"centuryOfEra": 20,
"hourOfDay": 17,
"secondOfDay": 61959,
"millis": 1678122759000,
"yearOfEra": 2023,
"minuteOfHour": 12,
"millisOfSecond": 0,
"afterNow": false
},
"paymentDelegatedToParent": false,
"name": "John Doe",
"timeZone": "UTC",
"currency": "USD",
"billCycleDayLocal": 0,
"email": "john@laposte.com"
}
],
"paginationNextOffset": 1,
"paginationNextPageUri": "/1.0/kb/accounts/pagination?offset=1&limit=1&accountWithBalanceAndCBA=false&accountWithBalance=false&audit=NONE",
"paginationMaxNbRecords": 5,
"killBillHttpClient": {},
"paginationCurrentOffset": 0,
"paginationTotalNbRecords": 5,
"empty": false
}
Query Parameters
Name | Type | Required | Default | Description |
---|---|---|---|---|
offset | long | false | 0 | Starting index for items listed |
limit | long | false | 100 | Maximum number of items to be listed |
accountWithBalance | boolean | false | false | If true, returns accountBalance info |
accountWithBalanceAndCBA | boolean | false | false | If true, returns accountBalance and accountCBA info |
Response
If successful, returns a status code of 200 and a list of all accounts.
Search accounts
Search for an account by a specified search string. The search string is compared to the following attributes: accountId
, name
, email
, companyName
, and externalKey
. The operation returns the account record in which the search string matches all or part of any one of the attributes name
, email
, companyName
, externalKey
. However, the string must match the entire attribute in case of accountId
.
For example : An account with name
exampleaccount can be searched using example as the search string. However, an account with accountId
9254283b-be25-45f1-97c3-b902f4d18bab cannot be searched using only 9254283b as the search string.
HTTP Request
GET http://127.0.0.1:8080/1.0/kb/accounts/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/accounts/search/John%20Doe"
import org.killbill.billing.client.api.gen.AccountApi;
protected AccountApi accountApi;
String searchKey = "John";
Long offset = 0L;
Long limit = 1L;
Boolean accountWithBalance = false; // Will not include account balance
Boolean accountWithBalanceAndCBA = false; // Will not include account balance and CBA info
List<Account> accountsByKey = accountApi.searchAccounts(searchKey,
offset,
limit,
accountWithBalance,
accountWithBalanceAndCBA,
AuditLevel.NONE,
requestOptions);
search_key = 'John'
offset = 0
limit = 100
with_balance = false
with_balance_and_cba = false
account.find_in_batches_by_search_key(search_key,
offset,
limit,
with_balance,
with_balance_and_cba,
options)
accountApi = killbill.api.AccountApi()
search_key = 'John'
accountApi.search_accounts(search_key, api_key, api_secret)
Example Response:
{
"next": [
{
"auditLogs": [],
"accountId": "fc693517-9ede-4543-a184-9e6f21119584",
"externalKey": "fc693517-9ede-4543-a184-9e6f21119584",
"referenceTime": {
"year": 2023,
"dayOfYear": 65,
"equalNow": false,
"weekyear": 2023,
"chronology": {
"zone": {
"ID": "UTC"
}
},
"weekOfWeekyear": 10,
"secondOfMinute": 21,
"millisOfDay": 62241000,
"monthOfYear": 3,
"dayOfWeek": 1,
"beforeNow": true,
"minuteOfDay": 1037,
"dayOfMonth": 6,
"era": 1,
"zone": {
"ID": "UTC"
},
"yearOfCentury": 23,
"hourOfDay": 17,
"centuryOfEra": 20,
"secondOfDay": 62241,
"millis": 1678123041000,
"yearOfEra": 2023,
"minuteOfHour": 17,
"millisOfSecond": 0,
"afterNow": false
},
"paymentDelegatedToParent": false,
"name": "John Doe",
"timeZone": "UTC",
"currency": "USD",
"billCycleDayLocal": 0,
"email": "john@laposte.com"
}
],
"paginationNextOffset": 1,
"paginationNextPageUri": "/1.0/kb/accounts/search/John?offset=1&limit=1&accountWithBalanceAndCBA=false&accountWithBalance=false&audit=NONE",
"paginationMaxNbRecords": 5,
"killBillHttpClient": {},
"paginationCurrentOffset": 0,
"paginationTotalNbRecords": 4,
"empty": false
}
Query Parameters
Name | Type | Required | Default | Description |
---|---|---|---|---|
searchKey | string | true | none | What you want to find |
offset | long | false | 0 | Starting index for items listed |
limit | long | false | 100 | Maximum number of items to return on this page |
accountWithBalance | boolean | false | false | If true, returns accountBalance info |
accountWithBalanceAndCBA | boolean | false | false | If true, returns accountBalance and accountCBA info |
audit | string | false | "NONE" | Level of audit information to return: "NONE", "MINIMAL", or "FULL" |
Response
If successful, returns a status code of 200 and a list of accounts that contain a match for the specified search key.
These endpoints manage emails associated with a customer account. These are secondary emails, distinct from the email
attribute in the account
object. It is possible to have
several such emails for one customer account.
Add account email
Add an email to an account. Existing emails are undisturbed.
HTTP Request
POST http://127.0.0.1:8080/1.0/kb/accounts/{accountId}/emails
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", "email": "email@laposte.com"}' \
"http://127.0.0.1:8080/1.0/kb/accounts/2ad52f53-85ae-408a-9879-32a7e59dd03d/emails"
import org.killbill.billing.client.api.gen.AccountApi;
protected AccountApi accountApi;
UUID accountId = UUID.fromString("873c26ef-a3fa-4942-b2f5-549b51f20b1a");
String email = "email@laposte.com";
AccountEmail accountEmail = new AccountEmail(accountId,
email,
AuditLevel.NONE);
accountApi.addEmail(accountId,
accountEmail,
requestOptions);
account.email = 'email@laposte.com'
account.add_email(account.email,
user,
reason,
comment,
options)
accountApi = killbill.api.AccountApi()
account_id = 'c84de569-b654-4f7f-ab13-17616302d310'
body = AccountEmail(account_id=account_id, email='email@laposte.com')
accountApi.add_email(account_id,
body,
created_by,
api_key,
api_secret)
Example Response:
no content
Request Body
The request body identifies a subset of the account
attributes as a JSON string. The attributes required are accountId
and email
(the email to be added). accountId
is required in the body even though it is given in the path. No other attributes should be included.
Query Parameters
None.
Response
If successful, returns a 201 status code. In addition, a Location
header is returned giving the URL for the account object, including the accountId
.
Retrieve account emails
Retrieves all emails for an account
HTTP Request
GET http://127.0.0.1:8080/1.0/kb/accounts/{accountId}/emails
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/accounts/2ad52f53-85ae-408a-9879-32a7e59dd03d/emails"
import org.killbill.billing.client.api.gen.AccountApi;
protected AccountApi accountApi;
UUID accountId = UUID.fromString("cd026587-c93b-471c-a98d-224c21636fbc");
List<AccountEmail> emails = accountApi.getEmails(accountId, requestOptions);
audit = 'NONE'
account.emails(audit, options)
accountApi = killbill.api.AccountApi()
account_id = 'c8f51346-562d-429b-8c89-27a0f72009b3'
accountApi.get_emails(account_id, api_key, api_secret)
Example Response:
[
{
"accountId":"e4ca38b3-934d-42e8-a292-ffb0af5549f2",
"email":"email@laposte.com"
}
]
Query Parameters
None.
Response Body
If successful, returns a status code of 200 and a list of objects giving the account id and the emails. Note that this is not the full object for each email, and does not include the email ID. This can be obtained only from the account audit log.
Delete email
Deletes an email from an account
HTTP Request
DELETE http://127.0.0.1:8080/1.0/kb/accounts/{accountId}/emails/{email}
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/accounts/2ad52f53-85ae-408a-9879-32a7e59dd03d/emails/email@laposte.com"
import org.killbill.billing.client.api.gen.AccountApi;
protected AccountApi accountApi;
UUID accountId = UUID.fromString("873c26ef-a3fa-4942-b2f5-549b51f20b1a");
String email = "email@laposte.com";
accountApi.removeEmail(accountId,
email,
requestOptions);
email = 'email@laposte.com'
account.remove_email(email,
user,
reason,
comment,
options)
accountApi = killbill.api.AccountApi()
account_id = 'c84de569-b654-4f7f-ab13-17616302d310'
email = 'email@laposte.com'
accountApi.remove_email(account_id,
email,
created_by,
api_key,
api_secret)
Example Response:
no content
Query Parameters
None.
Response
If successful, returns a status code of 204 and without any data.
Bundle
This endpoint provides an API to list the Bundles associated with this account. A Bundle is a set of Subscriptions and related information. See Bundle for details on Bundles.
Retrieve bundles for account
This endpoint is used to list all Bundles
associated with this account. It is possible to limit the list to a specific Bundle external key, or to a list of Bundle Ids.
HTTP Request
GET http://127.0.0.1:8080/1.0/kb/accounts/{accountId}/bundles
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/accounts/2ad52f53-85ae-408a-9879-32a7e59dd03d/bundles"
import org.killbill.billing.client.api.gen.AccountApi;
protected AccountApi accountApi;
UUID accountId = UUID.fromString("15434b45-54c1-4a44-851c-b1f2f7a52f03");
String externalKey = "123467"; //use null to fetch all bundles
String bundlesFilter = null;
List<Bundle> accountBundles = accountApi.getAccountBundles(accountId,
externalKey,
bundlesFilter,
AuditLevel.NONE,
requestOptions);
account.bundles(options)
accountApi = killbill.api.AccountApi()
account_id = '8992e146-bfa1-4126-a045-98b844a4adcb'
accountApi.get_account_bundles(account_id, api_key, api_secret)
Example Response:
[
{
"accountId": "2ad52f53-85ae-408a-9879-32a7e59dd03d",
"bundleId": "2cd2f4b5-a1c0-42a7-924f-64c7b791332d",
"externalKey": "2cd2f4b5-a1c0-42a7-924f-64c7b791332d",
"subscriptions": [
{
"accountId": "2ad52f53-85ae-408a-9879-32a7e59dd03d",
"bundleId": "2cd2f4b5-a1c0-42a7-924f-64c7b791332d",
"subscriptionId": "8ab101b6-15e8-433b-b4f7-f99eeaa56a77",
"externalKey": "2cd2f4b5-a1c0-42a7-924f-64c7b791332d",
"startDate": "2018-07-18",
"productName": "Standard",
"productCategory": "BASE",
"billingPeriod": "MONTHLY",
"phaseType": "TRIAL",
"priceList": "DEFAULT",
"planName": "standard-monthly",
"state": "ACTIVE",
"sourceType": "NATIVE",
"cancelledDate": null,
"chargedThroughDate": null,
"billingStartDate": "2018-07-18",
"billingEndDate": null,
"billCycleDayLocal": 17,
"events": [
{
"eventId": "3961e5a4-815c-4e95-aca6-2f3e76c37942",
"billingPeriod": "MONTHLY",
"effectiveDate": "2018-07-18",
"plan": "standard-monthly",
"product": "Standard",
"priceList": "DEFAULT",
"eventType": "START_ENTITLEMENT",
"isBlockedBilling": false,
"isBlockedEntitlement": false,
"serviceName": "entitlement-service",
"serviceStateName": "ENT_STARTED",
"phase": "standard-monthly-trial",
"auditLogs": []
},
{
"eventId": "8e7a6a7d-7660-49e3-979c-a4a0b6ec6804",
"billingPeriod": "MONTHLY",
"effectiveDate": "2018-07-18",
"plan": "standard-monthly",
"product": "Standard",
"priceList": "DEFAULT",
"eventType": "START_BILLING",
"isBlockedBilling": false,
"isBlockedEntitlement": false,
"serviceName": "billing-service",
"serviceStateName": "START_BILLING",
"phase": "standard-monthly-trial",
"auditLogs": []
},
{
"eventId": "f058c95f-9a86-435b-8bba-4f8532635450",
"billingPeriod": "MONTHLY",
"effectiveDate": "2018-08-17",
"plan": "standard-monthly",
"product": "Standard",
"priceList": "DEFAULT",
"eventType": "PHASE",
"isBlockedBilling": false,
"isBlockedEntitlement": false,
"serviceName": "entitlement+billing-service",
"serviceStateName": "PHASE",
"phase": "standard-monthly-evergreen",
"auditLogs": []
}
],
"priceOverrides": null,
"prices": [
{
"planName": "standard-monthly",
"phaseName": "standard-monthly-trial",
"phaseType": "TRIAL",
"fixedPrice": 0,
"recurringPrice": null,
"usagePrices": []
},
{
"planName": "standard-monthly",
"phaseName": "standard-monthly-evergreen",
"phaseType": "EVERGREEN",
"fixedPrice": null,
"recurringPrice": 100,
"usagePrices": []
}
],
"auditLogs": []
}
],
"timeline": {
"accountId": "2ad52f53-85ae-408a-9879-32a7e59dd03d",
"bundleId": "2cd2f4b5-a1c0-42a7-924f-64c7b791332d",
"externalKey": "2cd2f4b5-a1c0-42a7-924f-64c7b791332d",
"events": [
{
"eventId": "3961e5a4-815c-4e95-aca6-2f3e76c37942",
"billingPeriod": "MONTHLY",
"effectiveDate": "2018-07-18",
"plan": "standard-monthly",
"product": "Standard",
"priceList": "DEFAULT",
"eventType": "START_ENTITLEMENT",
"isBlockedBilling": false,
"isBlockedEntitlement": false,
"serviceName": "entitlement-service",
"serviceStateName": "ENT_STARTED",
"phase": "standard-monthly-trial",
"auditLogs": []
},
{
"eventId": "8e7a6a7d-7660-49e3-979c-a4a0b6ec6804",
"billingPeriod": "MONTHLY",
"effectiveDate": "2018-07-18",
"plan": "standard-monthly",
"product": "Standard",
"priceList": "DEFAULT",
"eventType": "START_BILLING",
"isBlockedBilling": false,
"isBlockedEntitlement": false,
"serviceName": "billing-service",
"serviceStateName": "START_BILLING",
"phase": "standard-monthly-trial",
"auditLogs": []
},
{
"eventId": "f058c95f-9a86-435b-8bba-4f8532635450",
"billingPeriod": "MONTHLY",
"effectiveDate": "2018-08-17",
"plan": "standard-monthly",
"product": "Standard",
"priceList": "DEFAULT",
"eventType": "PHASE",
"isBlockedBilling": false,
"isBlockedEntitlement": false,
"serviceName": "entitlement+billing-service",
"serviceStateName": "PHASE",
"phase": "standard-monthly-evergreen",
"auditLogs": []
}
],
"auditLogs": []
},
"auditLogs": []
}
]
Query Parameters
Name | Type | Required | Default | Description |
---|---|---|---|---|
externalKey | string | false | return all bundles | Bundle external key; if present, return only bundles with this key. |
bundlesFilter | string | false | return all bundles | Comma separated list of bundle ids to return, if found. |
audit | string | false | "NONE" | Level of audit information to return: "NONE", "MINIMAL", or "FULL" |
Returns
If successful, returns a status code of 200 and a list of bundle objects.
Retrieve paginated bundles for account
This endpoint is used to list all Bundles
associated with this account in a paginated format.
HTTP Request
GET http://127.0.0.1:8080/1.0/kb/accounts/{accountId}/bundles/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/accounts/325fbe1c-7c35-4d96-a4e5-2cbaabe218c6/bundles/pagination"
import org.killbill.billing.client.api.gen.AccountApi;
protected AccountApi accountApi;
UUID accountId = UUID.fromString("325fbe1c-7c35-4d96-a4e5-2cbaabe218c6");
Long offset = 0L;
Long limit = 10L;
Bundles bundles = accountApi.getAccountBundlesPaginated(accountId, offset, limit, AuditLevel.NONE, requestOptions);
account.bundles(options)
accountApi = killbill.api.AccountApi()
account_id = '8992e146-bfa1-4126-a045-98b844a4adcb'
accountApi.get_account_bundles_paginated(account_id, api_key, api_secret)
Example Response:
[
{
"accountId": "2ad52f53-85ae-408a-9879-32a7e59dd03d",
"bundleId": "2cd2f4b5-a1c0-42a7-924f-64c7b791332d",
"externalKey": "2cd2f4b5-a1c0-42a7-924f-64c7b791332d",
"subscriptions": [
{
"accountId": "2ad52f53-85ae-408a-9879-32a7e59dd03d",
"bundleId": "2cd2f4b5-a1c0-42a7-924f-64c7b791332d",
"subscriptionId": "8ab101b6-15e8-433b-b4f7-f99eeaa56a77",
"externalKey": "2cd2f4b5-a1c0-42a7-924f-64c7b791332d",
"startDate": "2018-07-18",
"productName": "Standard",
"productCategory": "BASE",
"billingPeriod": "MONTHLY",
"phaseType": "TRIAL",
"priceList": "DEFAULT",
"planName": "standard-monthly",
"state": "ACTIVE",
"sourceType": "NATIVE",
"cancelledDate": null,
"chargedThroughDate": null,
"billingStartDate": "2018-07-18",
"billingEndDate": null,
"billCycleDayLocal": 17,
"events": [
{
"eventId": "3961e5a4-815c-4e95-aca6-2f3e76c37942",
"billingPeriod": "MONTHLY",
"effectiveDate": "2018-07-18",
"plan": "standard-monthly",
"product": "Standard",
"priceList": "DEFAULT",
"eventType": "START_ENTITLEMENT",
"isBlockedBilling": false,
"isBlockedEntitlement": false,
"serviceName": "entitlement-service",
"serviceStateName": "ENT_STARTED",
"phase": "standard-monthly-trial",
"auditLogs": []
},
{
"eventId": "8e7a6a7d-7660-49e3-979c-a4a0b6ec6804",
"billingPeriod": "MONTHLY",
"effectiveDate": "2018-07-18",
"plan": "standard-monthly",
"product": "Standard",
"priceList": "DEFAULT",
"eventType": "START_BILLING",
"isBlockedBilling": false,
"isBlockedEntitlement": false,
"serviceName": "billing-service",
"serviceStateName": "START_BILLING",
"phase": "standard-monthly-trial",
"auditLogs": []
},
{
"eventId": "f058c95f-9a86-435b-8bba-4f8532635450",
"billingPeriod": "MONTHLY",
"effectiveDate": "2018-08-17",
"plan": "standard-monthly",
"product": "Standard",
"priceList": "DEFAULT",
"eventType": "PHASE",
"isBlockedBilling": false,
"isBlockedEntitlement": false,
"serviceName": "entitlement+billing-service",
"serviceStateName": "PHASE",
"phase": "standard-monthly-evergreen",
"auditLogs": []
}
],
"priceOverrides": null,
"prices": [
{
"planName": "standard-monthly",
"phaseName": "standard-monthly-trial",
"phaseType": "TRIAL",
"fixedPrice": 0,
"recurringPrice": null,
"usagePrices": []
},
{
"planName": "standard-monthly",
"phaseName": "standard-monthly-evergreen",
"phaseType": "EVERGREEN",
"fixedPrice": null,
"recurringPrice": 100,
"usagePrices": []
}
],
"auditLogs": []
}
],
"timeline": {
"accountId": "2ad52f53-85ae-408a-9879-32a7e59dd03d",
"bundleId": "2cd2f4b5-a1c0-42a7-924f-64c7b791332d",
"externalKey": "2cd2f4b5-a1c0-42a7-924f-64c7b791332d",
"events": [
{
"eventId": "3961e5a4-815c-4e95-aca6-2f3e76c37942",
"billingPeriod": "MONTHLY",
"effectiveDate": "2018-07-18",
"plan": "standard-monthly",
"product": "Standard",
"priceList": "DEFAULT",
"eventType": "START_ENTITLEMENT",
"isBlockedBilling": false,
"isBlockedEntitlement": false,
"serviceName": "entitlement-service",
"serviceStateName": "ENT_STARTED",
"phase": "standard-monthly-trial",
"auditLogs": []
},
{
"eventId": "8e7a6a7d-7660-49e3-979c-a4a0b6ec6804",
"billingPeriod": "MONTHLY",
"effectiveDate": "2018-07-18",
"plan": "standard-monthly",
"product": "Standard",
"priceList": "DEFAULT",
"eventType": "START_BILLING",
"isBlockedBilling": false,
"isBlockedEntitlement": false,
"serviceName": "billing-service",
"serviceStateName": "START_BILLING",
"phase": "standard-monthly-trial",
"auditLogs": []
},
{
"eventId": "f058c95f-9a86-435b-8bba-4f8532635450",
"billingPeriod": "MONTHLY",
"effectiveDate": "2018-08-17",
"plan": "standard-monthly",
"product": "Standard",
"priceList": "DEFAULT",
"eventType": "PHASE",
"isBlockedBilling": false,
"isBlockedEntitlement": false,
"serviceName": "entitlement+billing-service",
"serviceStateName": "PHASE",
"phase": "standard-monthly-evergreen",
"auditLogs": []
}
],
"auditLogs": []
},
"auditLogs": []
}
]
Query Parameters
Name | Type | Required | Default | Description |
---|---|---|---|---|
offset | long | false | 0 | Starting index for items listed |
limit | long | false | 100 | Maximum number of items to be listed |
audit | string | false | "NONE" | Level of audit information to return: "NONE", "MINIMAL", or "FULL" |
Returns
If successful, returns a status code of 200 and a list of bundle objects.
Invoice
This endpoint provides an API to list the Invoices associated with this account. See section Invoice for details on invoices.
Retrieve account invoices
List the Invoices associated with this account.
HTTP Request
GET http://127.0.0.1:8080/1.0/kb/accounts/{accountId}/invoices
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/accounts/2ad52f53-85ae-408a-9879-32a7e59dd03d/invoices"
import org.killbill.billing.client.api.gen.AccountApi;
protected AccountApi accountApi;
UUID accountId = UUID.fromString("d3a82897-ae72-4a2e-9bca-e3c1fe087f84");
LocalDate startDate = null;
LocalDate endDate = null;
Boolean withMigrationInvoices = false; // Will not fetch migrated invoice - if any
Boolean unpaidInvoicesOnly = false; // Will not restrict to unpaid invoices
Boolean includeVoidedInvoices = false; // Will not include void invoices
Boolean includeInvoiceComponents = false; //Will not include invoice components like invoice items/payments, etc.
String invoicesFilter = null;
Invoices invoices = accountApi.getInvoicesForAccount(accountId,
startDate,
endDate,
withMigrationInvoices,
unpaidInvoicesOnly,
includeVoidedInvoices,
includeInvoiceComponents,
invoicesFilter,
AuditLevel.FULL,
requestOptions);
account.invoices(with_items,
options)
accountApi = killbill.api.AccountApi()
account_id = '82ecbf80-ddd2-4208-92be-2d3b2b7fc266'
accountApi.get_invoices_for_account(account_id, api_key, api_secret)
Example Response:
[
{
"amount":50.0,
"currency":"USD",
"status":"COMMITTED",
"creditAdj":0.0,
"refundAdj":0.0,
"invoiceId":"d981abbb-3622-487a-9564-d594c9d04f83",
"invoiceDate":"2013-08-01",
"targetDate":"2013-08-01",
"invoiceNumber":"1563",
"balance":0.0,
"accountId":"2ad52f53-85ae-408a-9879-32a7e59dd03d",
"items":[
{
"invoiceItemId":"5f3b4e9c-66bd-4c5c-b84a-4ae951cc2f1d",
"invoiceId":"d981abbb-3622-487a-9564-d594c9d04f83",
"accountId":"2ad52f53-85ae-408a-9879-32a7e59dd03d",
"itemType":"EXTERNAL_CHARGE",
"description":"Some description",
"startDate":"2013-08-01",
"amount":50.0,
"currency":"USD",
"auditLogs":[]
}
],
"isParentInvoice":false,
"auditLogs":[]
}
]
Query Parameters
Name | Type | Required | Default | Description |
---|---|---|---|---|
startDate | date | false | no starting date | Return only invoices issued since this date. |
endDate | date | false | no ending date | Return only invoices issued up to this date. |
withMigrationInvoices | boolean | false | false | Choose true to include migration invoices |
unpaidInvoicesOnly | boolean | false | false | Choose true to include unpaid invoices only |
includeVoidedInvoices | boolean | false | false | Choose true to include voided invoices |
includeInvoiceComponents | boolean | false | false | Choose true to include invoice components (like invoice items/payments, etc.) |
invoicesFilter | string | false | empty | A comma separated list of invoiceIds to filter |
audit | string | false | "NONE" | Level of audit information to return: "NONE", "MINIMAL", or "FULL" |
For information about migration and migration invoices, see the Migration Guide.
Response
If successful, returns a status of 200 and a list of invoice objects for this account.
Retrieve paginated account invoices
List the Invoices associated with this account in a paginated format.
HTTP Request
GET http://127.0.0.1:8080/1.0/kb/accounts/{accountId}/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/accounts/325fbe1c-7c35-4d96-a4e5-2cbaabe218c6/invoices/pagination"
import org.killbill.billing.client.api.gen.AccountApi;
protected AccountApi accountApi;
UUID accountId = UUID.fromString("325fbe1c-7c35-4d96-a4e5-2cbaabe218c6");
Long offset = 0L;
Long limit = 10L;
Invoices invoices = accountApi.getInvoicesForAccountPaginated(accountId, offset, limit, AuditLevel.NONE, requestOptions);
account.invoices(with_items,
options)
accountApi = killbill.api.AccountApi()
account_id = '82ecbf80-ddd2-4208-92be-2d3b2b7fc266'
accountApi.get_invoices_for_account_paginated(account_id, api_key, api_secret)
Example Response:
[
{
"amount":50.0,
"currency":"USD",
"status":"COMMITTED",
"creditAdj":0.0,
"refundAdj":0.0,
"invoiceId":"d981abbb-3622-487a-9564-d594c9d04f83",
"invoiceDate":"2013-08-01",
"targetDate":"2013-08-01",
"invoiceNumber":"1563",
"balance":0.0,
"accountId":"2ad52f53-85ae-408a-9879-32a7e59dd03d",
"items":[
{
"invoiceItemId":"5f3b4e9c-66bd-4c5c-b84a-4ae951cc2f1d",
"invoiceId":"d981abbb-3622-487a-9564-d594c9d04f83",
"accountId":"2ad52f53-85ae-408a-9879-32a7e59dd03d",
"itemType":"EXTERNAL_CHARGE",
"description":"Some description",
"startDate":"2013-08-01",
"amount":50.0,
"currency":"USD",
"auditLogs":[]
}
],
"isParentInvoice":false,
"auditLogs":[]
}
]
Query Parameters
Name | Type | Required | Default | Description |
---|---|---|---|---|
offset | long | false | 0 | Starting index for items listed |
limit | long | false | 100 | Maximum number of items to be listed |
audit | string | false | "NONE" | Level of audit information to return: "NONE", "MINIMAL", or "FULL" |
For information about migration and migration invoices, see the Migration Guide.
Response
If successful, returns a status of 200 and a list of invoice objects for this account.
Payment
These endpoints are used to make or manage payments associated with this account. See section Payment for details on payments.
Trigger a payment for all unpaid invoices
Initiate payments for any unpaid invoices. This API allows you to make a series of payment calls, one against each unpaid invoice, using a specific payment method.
If successful, returns a 201 status code. In addition, a Location
header is returned giving the URL for fetching the paid invoices. If no payments were made, returns a 204 status code.
HTTP Request
POST http://127.0.0.1:8080/1.0/kb/accounts/{accountId}/invoicePayments
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/accounts/2ad52f53-85ae-408a-9879-32a7e59dd03d/invoicePayments?paymentMethodId=f835c556-0694-4883-b4c1-d1b6e308409b"
import org.killbill.billing.client.api.gen.AccountApi;
protected AccountApi accountApi;
UUID accountId = UUID.fromString("e011caa5-ba35-4ac6-81cb-63b4f08122dc");
UUID paymentMethodId = null;
Boolean externalPayment = true; // Will use a external payment method
BigDecimal paymentAmount = null;
LocalDate targetDate = null;
Map<String, String> NULL_PLUGIN_PROPERTIES = null;
accountApi.payAllInvoices(accountId,
paymentMethodId,
externalPayment,
paymentAmount,
targetDate,
NULL_PLUGIN_PROPERTIES,
requestOptions);
invoice_payment = KillBillClient::Model::InvoicePayment.new
invoice_payment.account_id = account.account_id
invoice_payment.purchased_amount = '50.0'
external_payment = true
payment_method_id = nil
target_date = nil
invoice_payment.bulk_create(external_payment,
payment_method_id,
target_date,
user,
reason,
comment,
options)
accountApi = killbill.api.AccountApi()
account_id = '82ecbf80-ddd2-4208-92be-2d3b2b7fc266'
accountApi.pay_all_invoices(account_id,
created_by,
api_key,
api_secret,
external_payment=True,
payment_method_id=None,
target_date=None)
Example Response:
no content
Query Parameters
Name | Type | Required | Default | Description |
---|---|---|---|---|
paymentMethodId | string | false | default payment method | Payment method id |
externalPayment | boolean | false | false | Choose true if you use a external payment method. |
paymentAmount | string | false | total balance | Total payment amount |
targetDate | string | false | current date | Date for which payment should be made |
Response
If successful, returns a status code of 204 without any data.
Retrieve account invoice payments
Retrieve a list of payments made against invoices for this account.
HTTP Request
GET http://127.0.0.1:8080/1.0/kb/accounts/{accountId}/invoicePayments
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/accounts/2ad52f53-85ae-408a-9879-32a7e59dd03d/invoicePayments"
import org.killbill.billing.client.api.gen.AccountApi;
protected AccountApi accountApi;
UUID accountId = UUID.fromString("e011caa5-ba35-4ac6-81cb-63b4f08122dc");
Map<String, String> NULL_PLUGIN_PROPERTIES = null;
InvoicePayments result = accountApi.getInvoicePayments(accountId,
NULL_PLUGIN_PROPERTIES,
requestOptions);
audit ='NONE'
with_plugin_info = false
with_attempts = false
account.invoice_payments(audit,
with_plugin_info,
with_attempts,
options)
accountApi = killbill.api.AccountApi()
account_id = '110952d7-1b7e-482c-b6bb-103e46794927'
accountApi.get_invoice_payments(account_id, api_key, api_secret)
Example Response:
[
{
"targetInvoiceId":"d1d6e8d8-c476-4b53-badf-c23f78c02c09",
"accountId":"2ad52f53-85ae-408a-9879-32a7e59dd03d",
"paymentId":"3f84661c-4fb7-42ac-8a02-3e8f48840e51",
"paymentNumber":"319",
"paymentExternalKey":"3f84661c-4fb7-42ac-8a02-3e8f48840e51",
"authAmount":0,
"capturedAmount":0,
"purchasedAmount":50.0,
"refundedAmount":0,
"creditedAmount":0,
"currency":"USD",
"paymentMethodId":"6c064894-60cb-4d7e-a679-7b2464522968",
"transactions":[
{
"transactionId":"91c7363c-76b9-48f5-aafa-f098d4470a2a",
"transactionExternalKey":"91c7363c-76b9-48f5-aafa-f098d4470a2a",
"paymentId":"3f84661c-4fb7-42ac-8a02-3e8f48840e51",
"paymentExternalKey":"3f84661c-4fb7-42ac-8a02-3e8f48840e51",
"transactionType":"PURCHASE",
"amount":50.0,
"currency":"USD",
"effectiveDate":"2013-08-01T06:00:01.000Z",
"processedAmount":50.0,
"processedCurrency":"USD",
"status":"SUCCESS",
"auditLogs":[]
}
],
"auditLogs":[]
}
]
Query Parameters
Name | Type | Required | Default | Description |
---|---|---|---|---|
withPluginInfo | boolean | false | false | Choose true to include plugin info |
withAttempts | boolean | false | false | Choose true to include payment attempts |
audit | string | false | "NONE" | Level of audit information to return: "NONE", "MINIMAL", or "FULL" |
Returns
If successful, returns a status code of 200 and a list of invoice payment objects.
Retrieve account payments
Retrieve a list of payments made for this account. Payments are listed independent of any invoice.
HTTP Request
GET http://127.0.0.1:8080/1.0/kb/accounts/{accountId}/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/accounts/2ad52f53-85ae-408a-9879-32a7e59dd03d/payments"
import org.killbill.billing.client.api.gen.AccountApi;
protected AccountApi accountApi;
UUID accountId = UUID.fromString("e0fe95af-7d59-4b70-8252-165e1840410c");
Boolean withAttempts = false; // Will not reflect payment attempts
Boolean withPluginInfo = false; // Will not reflect payment attempts
Map<String, String> NULL_PLUGIN_PROPERTIES = null;
Payments payments = accountApi.getPaymentsForAccount(accountId,
withAttempts,
withPluginInfo,
NULL_PLUGIN_PROPERTIES,
AuditLevel.NONE,
requestOptions);
account.payments(options)
accountApi = killbill.api.AccountApi()
account_id = 'b0da8392-49ba-43f2-8fac-3f9f85b8ff61'
accountApi.get_payments_for_account(account_id, api_key, api_secret)
Example Response:
[
{
"accountId":"2ad52f53-85ae-408a-9879-32a7e59dd03d",
"paymentId":"b83132eb-1bf9-4a02-8572-376e4b1f06c9",
"paymentNumber":"325",
"paymentExternalKey":"b83132eb-1bf9-4a02-8572-376e4b1f06c9",
"authAmount":0,
"capturedAmount":0,
"purchasedAmount":50.0,
"refundedAmount":0,
"creditedAmount":0,
"currency":"USD",
"paymentMethodId":"6041ffab-ae5f-45d3-bdf8-ce8cbfa5fd5c",
"transactions":[
{
"transactionId":"be9dceca-9c5d-4038-818c-57e6fccfbe92",
"transactionExternalKey":"be9dceca-9c5d-4038-818c-57e6fccfbe92",
"paymentId":"b83132eb-1bf9-4a02-8572-376e4b1f06c9",
"paymentExternalKey":"b83132eb-1bf9-4a02-8572-376e4b1f06c9",
"transactionType":"PURCHASE",
"amount":50.0,
"currency":"USD",
"effectiveDate":"2013-08-01T06:00:02.000Z",
"processedAmount":50.0,
"processedCurrency":"USD",
"status":"SUCCESS",
"auditLogs":[
]
}
],
"auditLogs":[]
}
]
Query Parameters
Name | Type | Required | Default | Description |
---|---|---|---|---|
withPluginInfo | boolean | false | false | Choose true to include plugin info |
withAttempts | boolean | false | false | Choose true to include payment attempts |
audit | string | false | "NONE" | Level of audit information to return: "NONE", "MINIMAL", or "FULL" |
Response
If successful, returns a status code of 200 and a list of payment objects.
Trigger a payment (authorization, purchase or credit)
This endpoint is part of the raw payment APIs, unreleated to subscriptions and invoices. It simply triggers a payment transaction against a particular payment gateway through the Kill Bill core and through the plugin communicating with the payment gateway. The transaction could be an authorization, a purchase, or a credit.
HTTP Request
POST http://127.0.0.1:8080/1.0/kb/accounts/{accountId}/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 '{ "transactionType": "AUTHORIZE", "amount": 0}' \
"http://127.0.0.1:8080/1.0/kb/accounts/2ad52f53-85ae-408a-9879-32a7e59dd03d/payments?paymentMethodId=c02fa9b0-ae95-42ae-9010-bc11cb160947"
import org.killbill.billing.client.api.gen.AccountApi;
protected AccountApi accountApi;
UUID accountId = UUID.fromString("f4087a76-9f8a-4893-abbf-c5bb69975d1b");
PaymentTransaction authTransaction = new PaymentTransaction();
authTransaction.setAmount(BigDecimal.ONE);
authTransaction.setCurrency(account.getCurrency());
// TransactionType could be 'AUTHORIZE', 'PURCHASE' or 'CREDIT'
authTransaction.setTransactionType(TransactionType.AUTHORIZE);
UUID paymentMethodId = UUID.fromString("1d55ed5f-deea-4109-98b0-beb13a242f7c");
List<String> NULL_PLUGIN_NAMES = null;
Map<String, String> NULL_PLUGIN_PROPERTIES = null;
Payment payment = accountApi.processPayment(accountId,
authTransaction,
paymentMethodId,
NULL_PLUGIN_NAMES,
NULL_PLUGIN_PROPERTIES,
requestOptions);
transaction = KillBillClient::Model::Transaction.new
transaction.amount = '50.0'
payment_method_id = payment_method.payment_method_id
refresh_options = nil
# Authorization
transaction.auth(account.account_id,
payment_method_id,
user,
reason,
comment,
options,
refresh_options)
# Purchase
transaction.purchase(account.account_id,
payment_method_id,
user,
reason,
comment,
options,
refresh_options)
# Credit
transaction.credit(account.account_id,
payment_method_id,
user,
reason,
comment,
options,
refresh_options)
accountApi = killbill.api.AccountApi()
account_id = 'b0da8392-49ba-43f2-8fac-3f9f85b8ff61'
payment_method_id = '80c7b386-97b2-424c-bb4e-0017f92bc6eb'
# transaction_type could be 'AUTHORIZE', 'PURCHASE' or 'CREDIT'
body = PaymentTransaction(amount=50, transaction_type='AUTHORIZE')
accountApi.process_payment(account_id,
body,
created_by,
api_key,
api_secret,
payment_method_id=payment_method_id)
Example Response:
{
"accountId":"2ad4cae9-c44a-43f9-b3f8-2e3e4e097838",
"paymentId":"b4c5b34f-cd3e-4269-9f71-55daf8edde60",
"paymentNumber":"333",
"paymentExternalKey":"b4c5b34f-cd3e-4269-9f71-55daf8edde60",
"authAmount":50.0,
"capturedAmount":0,
"purchasedAmount":0,
"refundedAmount":0,
"creditedAmount":0,
"currency":"USD",
"paymentMethodId":"132d59c0-8c28-4115-947d-f57d430bc458",
"transactions":[
{
"transactionId":"e038a04e-5304-4570-ab89-b7f04e8f496c",
"transactionExternalKey":"e038a04e-5304-4570-ab89-b7f04e8f496c",
"paymentId":"b4c5b34f-cd3e-4269-9f71-55daf8edde60",
"paymentExternalKey":"b4c5b34f-cd3e-4269-9f71-55daf8edde60",
"transactionType":"AUTHORIZE",
"amount":50.0,
"currency":"USD",
"effectiveDate":"2013-08-01T06:00:01.000Z",
"processedAmount":50.0,
"processedCurrency":"USD",
"status":"SUCCESS",
"auditLogs":[]
}
],
"auditLogs":[]
}
Request Body
The request body is a JSON string representing the payment transaction. See section Payment Transaction for details on payment transactions.
Query Parameters
Name | Type | Required | Default | Description |
---|---|---|---|---|
paymentMethodId | string | false | default payment method | payment method ID to use, if not default method |
controlPluginName | array of strings | false | omit | list of control plugins, if any |
pluginProperty | array of strings | false | omit | list of plugin properties, if any |
Response
If successful, returns a 201 status code. In addition, a Location
header is returned giving the URL for the payment object, including the generated paymentId
.
Trigger a payment (authorization, purchase or credit) using the account external key
This endpoint performs the same actions as the previous one, but the account is identified by its external key.
HTTP Request
POST http://127.0.0.1:8080/1.0/kb/accounts/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 '{ "transactionType": "AUTHORIZE", "amount": 0}' \
"http://127.0.0.1:8080/1.0/kb/accounts/payments?externalKey=2ad52f53-85ae-408a-9879-32a7e59dd03d&paymentMethodId=c02fa9b0-ae95-42ae-9010-bc11cb160947"
import org.killbill.billing.client.api.gen.AccountApi;
protected AccountApi accountApi;
String externalKey = "ad70ffb1-3355-418a-a457-6d8d80696d02";
PaymentTransaction authTransaction = new PaymentTransaction();
authTransaction.setAmount(BigDecimal.ONE);
authTransaction.setCurrency(Currency.USD);//use currency associated with Account
// TransactionType could be 'AUTHORIZE', 'PURCHASE' or 'CREDIT'
authTransaction.setTransactionType(TransactionType.AUTHORIZE);
UUID paymentMethodId = UUID.fromString("c6bd413e-268e-4cc8-afb0-16b2dec3ffa5");
List<String> NULL_PLUGIN_NAMES = null;
Map<String, String> NULL_PLUGIN_PROPERTIES = null;
Payment payment = accountApi.processPaymentByExternalKey(authTransaction,
externalKey,
paymentMethodId,
NULL_PLUGIN_NAMES,
NULL_PLUGIN_PROPERTIES,
requestOptions);
transaction = KillBillClient::Model::Transaction.new
transaction.amount = '50.0'
payment_method_id = '132d59c0-8c28-4115-947d-f57d430bc458'
refresh_options = nil
# Authorization
transaction.auth_by_external_key(account.external_key,
payment_method_id,
user,
reason,
comment,
options,
refresh_options)
# Purchase
transaction.purchase_by_external_key(account.external_key,
payment_method_id,
user,
reason,
comment,
options,
refresh_options)
# Credit
transaction.credit_by_external_key(account.external_key,
payment_method_id,
user,
reason,
comment,
options,
refresh_options)
accountApi = killbill.api.AccountApi()
account_external_key = 'sample_external_key'
payment_method_id = '80c7b386-97b2-424c-bb4e-0017f92bc6eb'
# transaction_type could be 'AUTHORIZE', 'PURCHASE' or 'CREDIT'
body = PaymentTransaction(amount=50, transaction_type='AUTHORIZE')
accountApi.process_payment_by_external_key(body,
external_key,
created_by,
api_key,
api_secret)
payment_method_id=payment_method_id)
Example Response:
{
"accountId":"2ad4cae9-c44a-43f9-b3f8-2e3e4e097838",
"paymentId":"b4c5b34f-cd3e-4269-9f71-55daf8edde60",
"paymentNumber":"333",
"paymentExternalKey":"b4c5b34f-cd3e-4269-9f71-55daf8edde60",
"authAmount":50.0,
"capturedAmount":0,
"purchasedAmount":0,
"refundedAmount":0,
"creditedAmount":0,
"currency":"USD",
"paymentMethodId":"132d59c0-8c28-4115-947d-f57d430bc458",
"transactions":[
{
"transactionId":"e038a04e-5304-4570-ab89-b7f04e8f496c",
"transactionExternalKey":"e038a04e-5304-4570-ab89-b7f04e8f496c",
"paymentId":"b4c5b34f-cd3e-4269-9f71-55daf8edde60",
"paymentExternalKey":"b4c5b34f-cd3e-4269-9f71-55daf8edde60",
"transactionType":"AUTHORIZE",
"amount":50.0,
"currency":"USD",
"effectiveDate":"2013-08-01T06:00:01.000Z",
"processedAmount":50.0,
"processedCurrency":"USD",
"status":"SUCCESS",
"auditLogs":[]
}
],
"auditLogs":[]
}
Request Body
The request body is a JSON string representing the payment transaction. See section Payment Transaction for details on payment transactions.
Query Parameters
Name | Type | Required | Default | Description |
---|---|---|---|---|
externalKey | string | true | none | the account external key |
paymentMethodId | string | false | default payment method | payment method ID to use, if not default method |
controlPluginName | array of strings | false | empty list | list of control plugins, if any |
pluginProperty | array of strings | false | empty list | list of plugin properties, if any |
Response
If successful, returns a 201 status code. In addition, a Location
header is returned giving the URL for the payment object, including the generated paymentId
.
Payment Method
These endpoints allow you to manage the payment methods for an account. See section Payment Method for details on payment methods.
Add a payment method
Add a payment method for a given Account
. The payment method is represented by a plugin that must already be registered with KillBill.
HTTP Request
POST http://127.0.0.1:8080/1.0/kb/accounts/{accountId}/paymentMethods
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 '{ "externalKey": "ExternalKey", "accountId": "2ad52f53-85ae-408a-9879-32a7e59dd03d", "pluginName": "__EXTERNAL_PAYMENT__"}' \
"http://127.0.0.1:8080/1.0/kb/accounts/8785164f-b5d7-4da1-9495-33f5105e8d80/paymentMethods"
import org.killbill.billing.client.api.gen.AccountApi;
protected AccountApi accountApi;
UUID accountId = UUID.fromString("6e5d0912-2e56-4511-af77-af054b616696");
String pluginName = "__EXTERNAL_PAYMENT__";
PaymentMethod paymentMethod = new PaymentMethod();
paymentMethod.setPluginName(pluginName);
List<String> NULL_PLUGIN_NAMES = null;
Map<String, String> NULL_PLUGIN_PROPERTIES = null;
//create a payment method
PaymentMethod paymentMethodPP = accountApi.createPaymentMethod(accountId, paymentMethod, NULL_PLUGIN_NAMES, NULL_PLUGIN_PROPERTIES, requestOptions);
//to create a payment method and set it as default use accountApi.createPaymentMethod(accountId, body, isDefault, payAllUnpaidInvoices, controlPluginName, pluginProperty, inputOptions);
pm = KillBillClient::Model::PaymentMethod.new
pm.account_id = account.account_id
pm.plugin_name = '__EXTERNAL_PAYMENT__'
pm.plugin_info = nil
is_default = true
pm.create(is_default,
user,
reason,
comment,
options)
accountApi = killbill.api.AccountApi()
account_id = '059ecfb8-6b4d-4a89-9537-63a687e6cf10'
body = PaymentMethod(external_key='ExternalKey', plugin_name='__EXTERNAL_PAYMENT__', plugin_info=None)
accountApi.create_payment_method(account_id,
body,
created_by,
api_key,
api_secret)
Example Response:
{
"paymentMethodId":"059ecfb8-6b4d-4a89-9537-63a687e6cf10",
"externalKey":"ExternalKey",
"accountId":"fa488b6e-c52a-450a-94bf-6607ae8b484f",
"isDefault":true,
"pluginName":"__EXTERNAL_PAYMENT__",
"pluginInfo":{
"properties":[]
},
"auditLogs":[]
}
Request Body
A payment method object specifying accountId
and pluginName
at the minimum. Please refer to the payment method resource section for more details about the fields.
Query Parameters
Name | Type | Required | Default | Description |
---|---|---|---|---|
isDefault | boolean | false | false | Choose true to set new payment as default. |
payAllUnpaidInvoices | boolean | false | false | Choose true to pay all unpaid invoices. |
controlPluginName | array of strings | false | empty list | list of control plugins, if any |
pluginProperty | array of strings | false | empty list | list of plugin properties, if any |
Response
If successful, returns a 201 status code. In addition, a Location
header is returned giving the URL for the payment method, including the generated paymentMethodId
.
Retrieve account payment methods
This API retrieves a list of the payment methods that are associated with this account.
HTTP Request
GET http://127.0.0.1:8080/1.0/kb/accounts/{accountId}/paymentMethods
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/accounts/2ad52f53-85ae-408a-9879-32a7e59dd03d/paymentMethods"
import org.killbill.billing.client.api.gen.AccountApi;
protected AccountApi accountApi;
UUID accountId = UUID.fromString("faf239a5-456a-4eb9-aef9-8d2254ef57dc");
Map<String, String> NULL_PLUGIN_PROPERTIES = null;
List<PaymentMethod> paymentMethods = accountApi.getPaymentMethodsForAccount(accountId,
NULL_PLUGIN_PROPERTIES,
requestOptions);
account_id = account.account_id
with_plugin_info = false
payment_method.find_all_by_account_id(account_id,
with_plugin_info,
options)
accountApi = killbill.api.AccountApi()
account_id = '88a5987a-1e1c-47c5-ba95-34ef14db3d46'
accountApi.get_payment_methods_for_account(account_id, api_key, api_secret)
Example Response:
[
{
"paymentMethodId": "f835c556-0694-4883-b4c1-d1b6e308409b",
"externalKey": "unknown",
"accountId": "2ad52f53-85ae-408a-9879-32a7e59dd03d",
"isDefault": false,
"pluginName": "__EXTERNAL_PAYMENT__",
"pluginInfo": null,
"auditLogs": []
}
]
Request Body
The request body is a JSON string representing any plugin specific payment information (payment token for exampe).
Query Parameters
Name | Type | Required | Default | Description |
---|---|---|---|---|
withPluginInfo | boolean | false | false | Choose true to include plugin info. |
includedDeleted | boolean | false | false | Choose true to include deleted payment methods |
pluginProperty | array of strings | false | empty list | list of plugin properties, if any |
audit | string | false | "NONE" | Level of audit information to return: "NONE", "MINIMAL", or "FULL" |
Response
If successful, returns a status code of 200 and a list of payment method objects.
Set the default payment method
This API sets an existing payment method to be the default payment method.
HTTP Request
PUT http://127.0.0.1:8080/1.0/kb/accounts/{accountId}/paymentMethods/{paymentMethodId}/setDefault
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/accounts/2ad52f53-85ae-408a-9879-32a7e59dd03d/paymentMethods/f835c556-0694-4883-b4c1-d1b6e308409b/setDefault"
import org.killbill.billing.client.api.gen.AccountApi;
protected AccountApi accountApi;
UUID accountId = UUID.fromString("faf239a5-456a-4eb9-aef9-8d2254ef57dc");
UUID paymentMethodId = UUID.fromString("faf239a5-456a-4eb9-aef9-8d2254ef57dc");
Map<String, String> NULL_PLUGIN_PROPERTIES = null;
accountApi.setDefaultPaymentMethod(accountId,
paymentMethodId,
NULL_PLUGIN_PROPERTIES,
requestOptions);
account_id = account.account_id
KillBillClient::Model::PaymentMethod.set_default(payment_method_id,
account_id,
user,
reason,
comment,
options)
accountApi = killbill.api.AccountApi()
account_id = '88a5987a-1e1c-47c5-ba95-34ef14db3d46'
payment_method_id = '4f124c0d-cee7-49b1-a181-3b0738c685d7'
accountApi.set_default_payment_method(account_id,
payment_method_id,
created_by,
api_key,
api_secret)
Example Response:
no content
Query Parameters
Name | Type | Required | Default | Description |
---|---|---|---|---|
payAllUnpaidInvoices | boolean | false | false | Choose true to pay all unpaid invoices |
pluginProperty | array of strings | false | empty list | List of plugin properties, if any |
Response
If successful, returns a status code of 204 and an empty body.
Refresh account payment methods
This endpoint is for a rare use case where information for a particular payment method is stored inside the third party gateway, and both Kill Bill core and its payment plugin need to have their view updated.
HTTP Request
PUT http://127.0.0.1:8080/1.0/kb/accounts/{accountId}/paymentMethods/refresh
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/accounts/2ad52f53-85ae-408a-9879-32a7e59dd03d/paymentMethods/refresh"
import org.killbill.billing.client.api.gen.AccountApi;
protected AccountApi accountApi;
UUID accountId = UUID.fromString("faf239a5-456a-4eb9-aef9-8d2254ef57dc");
String pluginName = "__EXTERNAL_PAYMENT__";
Map<String, String> NULL_PLUGIN_PROPERTIES = null;
accountApi.refreshPaymentMethods(accountId,
pluginName,
NULL_PLUGIN_PROPERTIES,
requestOptions);
account_id = account.account_id
KillBillClient::Model::PaymentMethod.refresh(account_id,
user,
reason,
comment,
options)
accountApi = killbill.api.AccountApi()
account_id = '88a5987a-1e1c-47c5-ba95-34ef14db3d46'
accountApi.refresh_payment_methods(account_id,
created_by,
api_key,
api_secret)
Example Response:
no content
Query Parameters
Name | Type | Required | Default | Description |
---|---|---|---|---|
PluginName | array of strings | false | empty list | List of plugins, if any |
pluginProperty | array of strings | false | empty list | List of plugin properties, if any |
Response
If successful, returns a status code of 204 and an empty body.
Overdue
The system can be configured to move an Account
through various overdue (a.k.a. dunning) states when invoices are left unpaid.
Retrieve overdue state for account
Retrieve the current overdue/dunning state for an Account
.
HTTP Request
GET http://127.0.0.1:8080/1.0/kb/accounts/{accountId}/overdue
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/accounts/2ad52f53-85ae-408a-9879-32a7e59dd03d/overdue"
import org.killbill.billing.client.api.gen.AccountApi;
protected AccountApi accountApi;
UUID accountId = UUID.fromString("d3a82897-ae72-4a2e-9bca-e3c1fe087f84");
OverdueState result = accountApi.getOverdueAccount(accountId, requestOptions);
account.overdue(options)
accountApi = killbill.api.AccountApi()
account_id = '82ecbf80-ddd2-4208-92be-2d3b2b7fc266'
accountApi.get_overdue_account(account_id, api_key, api_secret)
Example Response:
{
"name": "__KILLBILL__CLEAR__OVERDUE_STATE__",
"externalMessage": "",
"daysBetweenPaymentRetries": [
8,
8,
8
],
"isDisableEntitlementAndChangesBlocked": false,
"isBlockChanges": false,
"isClearState": true,
"reevaluationIntervalDays": null
}
Query Parameters
None.
Returns
If successful, returns a status code of 200 and an overdue state object.
Blocking State
As part of the entitlement features, Kill Bill provides an abstraction to include BlockingState
events into the per Account
event stream. The main idea is to allow billing to be modified, such as by pausing a specific subscription or all subscriptions, and to allow modification of the entitlement state, such as by disabling the service associated with a given subscription. The entitlement internal documentation provides some overview of the mechanism. Blocking states are mostly manipulated from inside Kill Bill core, but the functionality is exposed through the API, with the caveat that it is an advanced feature and can lead to unintented behavior if not used properly.
Note that the term BlockingState
seems to indicate that something will be blocked, and this can certainly be the case, but not necessarily; actually the attributes
isBlockChange
, isBlockEntitlement
, isBlockBilling
will drive this behavior. These flags are always considered on a per blocking state service
, regardless of the state name. For instance, consider the following two scenarios:
- Scenario 1
- T1: Service A, State S1, isBlockBilling=true, isBlockEntitlement=false
- T2: Service A, State S1, isBlockBilling=false, isBlockEntitlement=true
- T3: Service A, State S2, isBlockBilling=false, isBlockEntitlement=false
- T4: Service A, State S2, isBlockBilling=false, isBlockEntitlement=false
- Scenario 2
- T1: Service A, State S1, isBlockBilling=true, isBlockEntitlement=false
- T2: Service B, State S1, isBlockBilling=false, isBlockEntitlement=true
- T3: Service A, State S2, isBlockBilling=false, isBlockEntitlement=false
- T4: Service B, State S2, isBlockBilling=false, isBlockEntitlement=false
In Scenario 1, billing is blocked between T1 and T2, while entitlement is blocked between T2 and T3. In Scenario 2 however, billing is blocked between T1 and T3, while entitlement is blocked between T2 and T4.
Blocking State Resource
A Blocking State Resource represents a blocking state. It has the following attributes:
Name | Type | Generated by | Description |
---|---|---|---|
blockedId | string | system | UUID for this blocking state id |
stateName | string | user | Name of the blocking state |
service | string | user | Name of the service that inserts the blocking state |
isBlockChange | boolean | user | Boolean flag that indicates whether changes should be blocked |
isBlockEntitlement | boolean | user | Boolean flag that indicates whether the entitlement should be blocked |
isBlockBilling | boolean | user | Boolean flag that indicates whether billing should be blocked |
effectiveDate | DateTime | user | DateTime that the change should be effective |
type | string | user | Type of blocking state. Possible values are SUBSCRIPTION, SUBSCRIPTION_BUNDLE and ACCOUNT |
Block an account
Add a BlockingState
event for this account.
HTTP Request
POST http://127.0.0.1:8080/1.0/kb/accounts/{accountId}/block
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 '{ "stateName": "STATE1", "service": "ServiceStateService", "isBlockChange": false, "isBlockEntitlement": false, "isBlockBilling": false }' \
"http://127.0.0.1:8080/1.0/kb/accounts/10483c3a-3394-4667-8519-0d849e9a8ec2/block"
import org.killbill.billing.client.api.gen.AccountApi;
protected AccountApi accountApi;
UUID accountId = UUID.fromString("864c1418-e768-4cd5-a0db-67537144b685");
BlockingState blockingState = new BlockingState();
blockingState.setStateName("STATE1");
blockingState.setService("ServiceStateService");
blockingState.setIsBlockChange(false);
blockingState.setIsBlockBilling(false);
blockingState.setIsBlockEntitlement(false);
LocalDate requestedDate = new LocalDate("2013-08-01");
Map<String, String> pluginProperty = Collections.emptyMap();
BlockingStates result = accountApi.addAccountBlockingState(accountId,
blockingState,
requestedDate,
pluginProperty,
requestOptions);
state_name = "STATE1"
service = "ServiceStateService"
block_change = false
block_entitlement = false
block_billing = false
requested_date = "2013-08-01"
account.set_blocking_state(state_name,
service,
block_change,
block_entitlement,
block_billing,
requested_date,
user,
reason,
comment,
options)
accountApi = killbill.api.AccountApi()
account_id = '07c0cef4-41c5-4606-b2cd-661332cdd41c'
body = BlockingState(state_name='STATE1',
service='ServiceStateService',
is_block_change=False,
is_block_entitlement=False,
is_block_billing=False)
accountApi.add_account_blocking_state(account_id,
body,
created_by,
api_key,
api_secret)
Example Response:
no content
Request Body
A JSON string representing the blocking state object to be added. For details on this resource see blocking state.
Query Parameters
Name | Type | Required | Default | Description |
---|---|---|---|---|
requestedDate | string | false | block immediately | Date/DateTime to block an account in yyyy-mm-dd /yyyy-mm-ddThh:mm format. |
pluginProperty | array of strings | false | empty list | List of plugin properties, if any |
Response
If successful, returns a 201 status code. In addition, a Location
header is returned giving the URL for retrieving blocking states for the account.
Retrieve blocking states for account
Retrieves the BlockingState
associated with a given resource.
BlockingState
can be set at the Account
, Bundle
or Subscription
level.
HTTP Request
GET http://127.0.0.1:8080/1.0/kb/accounts/{accountId}/block
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/accounts/10483c3a-3394-4667-8519-0d849e9a8ec2/block?blockingStateTypes=ACCOUNT"
import org.killbill.billing.client.api.gen.AccountApi;
protected AccountApi accountApi;
UUID accountId = UUID.fromString("ee6835f0-8347-42d3-958c-9a939383ba28");
List<BlockingStateType> blockingStateTypes = List.of(BlockingStateType.SUBSCRIPTION_BUNDLE);
List<String> blockingStateSvcs = List.of("service");
BlockingStates blockingStates = accountApi.getBlockingStates(accountId,
blockingStateTypes,
blockingStateSvcs,
AuditLevel.FULL,
requestOptions);
blocking_state_types = 'ACCOUNT'
blocking_state_svcs = nil
audit = 'NONE'
account.blocking_states(blocking_state_types,
blocking_state_svcs,
audit,
options)
accountApi = killbill.api.AccountApi()
account_id = '07c0cef4-41c5-4606-b2cd-661332cdd41c'
accountApi.get_blocking_states(account_id, api_key, api_secret)
Example Response:
[
{
"blockedId": "10483c3a-3394-4667-8519-0d849e9a8ec2",
"stateName": "STATE1",
"service": "ServiceStateService",
"isBlockChange": false,
"isBlockEntitlement": false,
"isBlockBilling": false,
"effectiveDate": "2018-07-18T14:45:37.000Z",
"type": "ACCOUNT",
"auditLogs": []
}
]
Query Parameters
Name | Type | Required | Default | Description |
---|---|---|---|---|
blockingStateTypes | array of strings | false | retrieve all | blocking state types to retrieve: "SUBSCRIPTION", "SUBSCRIPTION_BUNDLE", "ACCOUNT" |
blockingStateSvcs | array of strings | false | retrieve all | filter list for blocking state services |
audit | string | false | "NONE" | Level of audit information to return: "NONE", "MINIMAL", or "FULL" |
Response
If successful, returns a status code of 200 and a blocking state object.
Hierarchical Accounts
When using the hierarchical account feature, this API allows you to retrieve
all the child Accounts
for a given parent Account
.
List child accounts
HTTP Request
GET http://127.0.0.1:8080/1.0/kb/accounts/{accountId}/children
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/accounts/2ad52f53-85ae-408a-9879-32a7e59dd03d/children"
import org.killbill.billing.client.api.gen.AccountApi;
protected AccountApi accountApi;
UUID parentAccountId = UUID.fromString("ee6835f0-8347-42d3-958c-9a939383ba28");
Boolean accountWithBalance = true; // Will include account balance
Boolean accountWithBalanceAndCBA = true; // Will include account balance and CBA info
Accounts childrenAccounts = accountApi.getChildrenAccounts(parentAccountId,
accountWithBalance,
accountWithBalanceAndCBA,
AuditLevel.NONE,
requestOptions);
account_id = account.account_id
with_balance = false
with_balance_and_cba = false
audit = 'NONE'
childrens_account = KillBillClient::Model::Account.children(account_id,
with_balance,
with_balance_and_cba,
audit,
options)
accountApi = killbill.api.AccountApi()
account_id = '8992e146-bfa1-4126-a045-98b844a4adcb'
accountApi.get_children_accounts(account_id, api_key, api_secret)
Example Response:
[
{
"accountId":"e19c6ab3-1a21-42f2-8ea2-9859c082b093",
"name":"John Doe",
"externalKey":"1522172592-516014",
"email":"John@laposte.com",
"billCycleDayLocal":0,
"currency":"USD",
"parentAccountId":"01ab962b-3c66-4b17-b391-ffcc9fe51884",
"isPaymentDelegatedToParent":true,
"timeZone":"UTC",
"address1":"7, yoyo road",
"address2":"Apt 5",
"postalCode":"94105",
"company":"Unemployed",
"city":"San Francisco",
"state":"California",
"country":"US",
"locale":"fr_FR",
"auditLogs":[]
}
]
Query Parameters
Name | Type | Required | Default | Description |
---|---|---|---|---|
accountWithBalance | boolean | false | false | if true, returns accountBalance info |
accountWithBalanceAndCBA | boolean | false | false | if true, returns accountBalance and accountCBA info |
audit | string | false | "NONE" | Level of audit information to return: "NONE", "MINIMAL", or "FULL" |
Response
If successful, returns a status code of 200 and a list of child account objects.
Transfer a given child credit to the parent level
In the context of the Hierarchical Account feature, this allows moving the potential child credit to the parent level.
HTTP Request
PUT http://127.0.0.1:8080/1.0/kb/accounts/{childAccountId}/transferCredit
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/accounts/2ad52f53-85ae-408a-9879-32a7e59dd03d/transferCredit"
import org.killbill.billing.client.api.gen.AccountApi;
protected AccountApi accountApi;
UUID childAccountId = UUID.fromString("e659f0f3-745c-46d5-953c-28fe9282fc7d");
accountApi.transferChildCreditToParent(childAccountId, requestOptions);
account.transfer_child_credit(user,
reason,
comment,
options)
accountApi = killbill.api.AccountApi()
child_account_id = '88a5987a-1e1c-47c5-ba95-34ef14db3d46'
accountApi.transfer_child_credit_to_parent(child_account_id,
created_by,
api_key,
api_secret)
Example Response:
no content
Query Parameters
None.
Response
If successful, returns a status code of 204 and an empty body.
Custom Fields
Custom fields are {key, value}
attributes that can be attached to any customer resource. In particular they can be added to the customer Account
. For details on Custom Fields see Custom Field.
Add custom fields to account
Add custom fields to a given Account
.
HTTP Request
POST http://127.0.0.1:8080/1.0/kb/accounts/{accountId}/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": "ACCOUNT", "name": "Test Custom Field", "value": "demo_test_value" }]' \
"http://127.0.0.1:8080/1.0/kb/accounts/2ad52f53-85ae-408a-9879-32a7e59dd03d/customFields"
import org.killbill.billing.client.api.gen.AccountApi;
protected AccountApi accountApi;
UUID accountId = UUID.fromString("15434b45-54c1-4a44-851c-b1f2f7a52f03");
final List<AuditLog> EMPTY_AUDIT_LOGS = Collections.emptyList();
CustomFields customFields = new CustomFields();
customFields.add(new CustomField(null,
accountId,
ObjectType.ACCOUNT,
"Test Custom Field",
"test_value",
EMPTY_AUDIT_LOGS));
accountApi.createAccountCustomFields(accountId,
customFields,
requestOptions);
custom_field = KillBillClient::Model::CustomFieldAttributes.new
custom_field.object_type = 'ACCOUNT'
custom_field.name = 'Test Custom Field'
custom_field.value = 'test_value'
account.add_custom_field(custom_field,
user,
reason,
comment,
options)
accountApi = killbill.api.AccountApi()
account_id = '8992e146-bfa1-4126-a045-98b844a4adcb'
body = CustomField(name='Test Custom Field', value='test_value')
accountApi.create_account_custom_fields(account_id,
[body],
created_by,
api_key,
api_secret)
Example Response:
[
{
"customFieldId":"6e571e22-b794-413c-be6f-1b2aa4bf9824",
"objectId":"0149ffc6-fdfd-40b1-8cf4-29a66aef51d4",
"objectType":"ACCOUNT",
"name":"Test Custom Field",
"value":"test_value",
"auditLogs":[]
}
]
Request Body
A list of objects giving the name and value of the custom field, or fields, to be added. For example:
[ { "name": "CF1", "value": "123" } ]
Query Parameters
None.
Response
If successful, returns a 201 status code. In addition, a Location
header is returned giving the URL to retrieve the custom fields associated with the account.
Retrieve all custom fields
Retrieves all custom fields attached to various resources owned by the Account
.
This endpoint allows you to retrieve all custom fields, or to filter them by type, e.g Subscription
.
HTTP Request
GET http://127.0.0.1:8080/1.0/kb/accounts/{accountId}/allCustomFields
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/accounts/2ad52f53-85ae-408a-9879-32a7e59dd03d/allCustomFields"
import org.killbill.billing.client.api.gen.AccountApi;
protected AccountApi accountApi;
UUID accountId = UUID.fromString("b38de59f-7dd0-447a-a508-9b022b808250");
CustomFields allAccountCustomFields = accountApi.getAllCustomFields(accountId,
ObjectType.ACCOUNT,
AuditLevel.FULL,
requestOptions);
accountApi = killbill.api.AccountApi()
account_id = '07c0cef4-41c5-4606-b2cd-661332cdd41c'
accountApi.get_all_custom_fields(account_id,
api_key,
api_secret,
object_type='ACCOUNT')
object_type = 'ACCOUNT'
audit = 'NONE'
account.all_custom_fields(object_type,
audit,
options)
Example Response:
[
{
"customFieldId": "48e24ca0-1cfe-41c3-85e7-0ff0d51679fe",
"objectId": "2ad52f53-85ae-408a-9879-32a7e59dd03d",
"objectType": "ACCOUNT",
"name": "Test Custom Field",
"value": "test_value",
"auditLogs": []
}
]
Query Parameters
Name | Type | Required | Default | Description |
---|---|---|---|---|
objectType | string | false | retrieve all | type of object |
audit | string | false | "NONE" | Level of audit information to return: "NONE", "MINIMAL", or "FULL" |
Possible values for objectType are ACCOUNT, ACCOUNT_EMAIL, BLOCKING_STATES, BUNDLE, CUSTOM_FIELD, INVOICE, PAYMENT, TRANSACTION, INVOICE_ITEM, INVOICE_PAYMENT, SUBSCRIPTION, SUBSCRIPTION_EVENT, SERVICE_BROADCAST, PAYMENT_ATTEMPT, PAYMENT_METHOD, TAG, TAG_DEFINITION, TENANT, or TENANT_KVS.
Response
If successful, returns a status code of 200 and a list of custom field objects
Retrieve account custom fields
Retrieve the custom fields associated with an account
HTTP Request
GET http://127.0.0.1:8080/1.0/kb/accounts/{accountId}/customFields
Example Request:
curl -v \
-u admin:password \
-H "X-Killbill-ApiKey: bob" \
-H "X-Killbill-ApiSecret: lazar" \
-H "Accept: application/json" \
"http://localhost:8080/1.0/kb/accounts/2ad52f53-85ae-408a-9879-32a7e59dd03d/customFields"
import org.killbill.billing.client.api.gen.AccountApi;
protected AccountApi accountApi;
UUID accountId = UUID.fromString("59860a0d-c032-456d-a35e-3a48fe8579e5");
List<CustomField> accountCustomFields = accountApi.getAccountCustomFields(accountId,
AuditLevel.NONE,
requestOptions);
audit = 'NONE'
account.custom_fields(audit, options)
accountApi = killbill.api.AccountApi()
account_id = '8992e146-bfa1-4126-a045-98b844a4adcb'
accountApi.get_account_custom_fields(account_id, api_key, api_secret)
Example Response:
[
{
"customFieldId": "48e24ca0-1cfe-41c3-85e7-0ff0d51679fe",
"objectId": "2ad52f53-85ae-408a-9879-32a7e59dd03d",
"objectType": "ACCOUNT",
"name": "Test Custom Field",
"value": "test_value",
"auditLogs": []
}
]
Query Parameters
Name | Type | Required | Default | Description |
---|---|---|---|---|
audit | string | false | "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 account
Modify the custom fields associated with an account. 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/accounts/{accountId}/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": "48e24ca0-1cfe-41c3-85e7-0ff0d51679fe", "objectId": "2ad52f53-85ae-408a-9879-32a7e59dd03d", "objectType": "ACCOUNT", "name": "Test Custom Field", "value": "test_modify_value", "auditLogs": [] }]' \
"http://localhost:8080/1.0/kb/accounts/2ad52f53-85ae-408a-9879-32a7e59dd03d/customFields"
import org.killbill.billing.client.api.gen.AccountApi;
protected AccountApi accountApi;
UUID accountId = 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);
accountApi.modifyAccountCustomFields(accountId,
customFields,
requestOptions);
custom_field.custom_field_id = '7fb3dde7-0911-4477-99e3-69d142509bb9'
custom_field.name = 'Test Modify'
custom_field.value = 'test_modify_value'
account.modify_custom_field(custom_field,
user,
reason,
comment,
options)
account = killbill.api.AccountApi()
body = CustomField(custom_field_id=custom_field_id,
name='Test Custom Field',
value='test_value')
account.modify_account_custom_fields(account_id,
[body],
created_by,
api_key,
api_secret)
Example Response:
no content
Request Body
A list of objects specifying the id and the new value for the custom fields to be modified. For example:
[ { "customFieldId": "6d4c073b-fd89-4e39-9802-eba65f42492f", "value": "123" } ]
Although the fieldName
and objectType
can be specified in the request body, these cannot be modified, only the field value can be modified.
Query Parameters
None.
Returns
If successful, a status code of 204 and an empty body.
Remove custom fields from account
Remove a specified set of custom fields from the account
HTTP Request
DELETE http://127.0.0.1:8080/1.0/kb/accounts/{accountId}/customField
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/accounts/2ad52f53-85ae-408a-9879-32a7e59dd03d/customFields?customField=9913e0f6-b5ef-498b-ac47-60e1626eba8f"
import org.killbill.billing.client.api.gen.AccountApi;
protected AccountApi accountApi;
UUID accountId = UUID.fromString("59860a0d-c032-456d-a35e-3a48fe8579e5");
UUID customFieldsId = UUID.fromString("9913e0f6-b5ef-498b-ac47-60e1626eba8f");
List<UUID> customFieldsList = List.of(customFieldsId);
accountApi.deleteAccountCustomFields(accountId,
customFieldsList,
requestOptions);
custom_field_id = custom_field.id
account.remove_custom_field(custom_field_id,
user,
reason,
comment,
options)
account = killbill.api.AccountApi()
account_id = '8992e146-bfa1-4126-a045-98b844a4adcb'
custom_field_id = '9913e0f6-b5ef-498b-ac47-60e1626eba8f'
custom_field = [custom_field_id]
account.delete_account_custom_fields(account_id,
created_by,
api_key,
api_secret,
custom_field=custom_field)
Example Response:
no content
Query Parameters
Name | Type | Required | Default | Description |
---|---|---|---|---|
customField | string | true | 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
While custom fields allow you to attach {key, value}
pairs to various objects in the system, single values can also be
attached to various objects in the system by using tags. Tags come in 2 different categories:
System Tags
: These are interpreted by the system to change its behavior. Certain tags can only be attached to specific resource types -- e.gAccount
. In order to distinguish them from the user tags, the system tags are uppercase symbols.User Tags
: These are not interpreted by the system and can be anything as long as it a lowercase symbol. Foe example,good_customer
could be a tag that can be attached to a customerAccount
.
The APIs to manage tags rely on having an existing tag definition and supplying the tagDefinitionId
in the calls. Therefore, for user tags, one should first create a TagDefinition
.
To create user tags, one must first create the tag definitions. For instructions see section Tag definition.
Add tags to account
This API adds one or more tags to an account. The tag definitions must already exist.
HTTP Request
POST http://127.0.0.1:8080/1.0/kb/accounts/{accountId}/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-000000000002"]' \
"http://127.0.0.1:8080/1.0/kb/accounts/2ad52f53-85ae-408a-9879-32a7e59dd03d/tags"
import org.killbill.billing.client.api.gen.AccountApi;
protected AccountApi accountApi;
UUID accountId = UUID.fromString("f4087a76-9f8a-4893-abbf-c5bb69975d1b");
UUID autoPayOffTagId = UUID.fromString("00000000-0000-0000-0000-000000000001");
Tags result = accountApi.createAccountTags(accountId,
List.of(autoPayOffTagId),
requestOptions);
tag_name = 'TEST'
account.add_tag(tag_name,
user,
reason,
comment,
options)
accountApi = killbill.api.AccountApi()
account_id = 'b0da8392-49ba-43f2-8fac-3f9f85b8ff61'
tag = ["00000000-0000-0000-0000-000000000002"]
accountApi.create_account_tags(account_id,
tag,
created_by,
api_key,
api_secret)
Example Response:
[
{
"tagId":"a46cfeb6-e175-42db-be62-7f117326ab4e",
"objectType":"ACCOUNT",
"objectId":"28af3cb9-275b-4ac4-a55d-a0536e479069",
"tagDefinitionId":"00000000-0000-0000-0000-000000000006",
"tagDefinitionName":"TEST",
"auditLogs":[
]
}
]
Request Body
A JSON array containing one or more tag definition ids to be added as user tags.
Query Parameters
None.
Returns
If successful, returns a 201 status code. In addition, a Location
header is returned giving the URL to retrieve the tags associated with the account.
Retrieve all tags
Retrieves all tags attached to resources owned by this Account
. This API allows you to retrieve all tags, or only tags attached to a specified resource type.
HTTP Request
GET http://127.0.0.1:8080/1.0/kb/accounts/{accountId}/allTags
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/accounts/2ad52f53-85ae-408a-9879-32a7e59dd03d/allTags"
import org.killbill.billing.client.api.gen.AccountApi;
protected AccountApi accountApi;
UUID accountId = UUID.fromString("ee6835f0-8347-42d3-958c-9a939383ba28");
Tags allAccountTags = accountApi.getAllTags(accountId,
ObjectType.ACCOUNT,
requestOptions);
accountApi = killbill.api.AccountApi()
account_id = '07c0cef4-41c5-4606-b2cd-661332cdd41c'
accountApi.get_account_tags(account_id, api_key, api_secret)
object_type = 'ACCOUNT'
included_deleted = false
audit = 'NONE'
account.all_tags(object_type,
included_deleted,
audit,
options)
Example Response:
[
{
"tagId": "0f7c5837-1ed9-41ab-b391-9ef7ea4ab049",
"objectType": "ACCOUNT",
"objectId": "2ad52f53-85ae-408a-9879-32a7e59dd03d",
"tagDefinitionId": "00000000-0000-0000-0000-000000000002",
"tagDefinitionName": "AUTO_INVOICING_OFF",
"auditLogs": []
}
]
Query Parameters
Name | Type | Required | Default | Description |
---|---|---|---|---|
objectType | string | false | all object types | choose type of object |
includedDeleted | boolean | false | false | choose true to include deleted tags |
audit | string | false | "NONE" | Level of audit information to return: "NONE", "MINIMAL", or "FULL" |
Possible values for objectType are ACCOUNT, ACCOUNT_EMAIL, BLOCKING_STATES, BUNDLE, CUSTOM_FIELD, INVOICE, PAYMENT, TRANSACTION, INVOICE_ITEM, INVOICE_PAYMENT, SUBSCRIPTION, SUBSCRIPTION_EVENT, SERVICE_BROADCAST, PAYMENT_ATTEMPT, PAYMENT_METHOD, TAG, TAG_DEFINITION, TENANT, or TENANT_KVS.
Response
If successful, returns a status code of 200 and a list of tag objects.
Retrieve account tags
Retrieve all tags attached to this account itself.
HTTP Request
GET http://127.0.0.1:8080/1.0/kb/accounts/{accountId}/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/accounts/2ad52f53-85ae-408a-9879-32a7e59dd03d/tags"
import org.killbill.billing.client.api.gen.AccountApi;
protected AccountApi accountApi;
UUID accountId = UUID.fromString("e659f0f3-745c-46d5-953c-28fe9282fc7d");
Boolean includedDeleted = false; // Will not include deleted tags
List<Tag> tags1 = accountApi.getAccountTags(accountId,
includedDeleted,
AuditLevel.FULL,
requestOptions);
included_deleted = false
audit = 'NONE'
account.tags(included_deleted,
audit,
options)
accountApi = killbill.api.AccountApi()
account_id = 'b0da8392-49ba-43f2-8fac-3f9f85b8ff61'
accountApi.get_account_tags(account_id, api_key, api_secret)
Example Response:
[
{
"tagId": "0f7c5837-1ed9-41ab-b391-9ef7ea4ab049",
"objectType": "ACCOUNT",
"objectId": "2ad52f53-85ae-408a-9879-32a7e59dd03d",
"tagDefinitionId": "00000000-0000-0000-0000-000000000002",
"tagDefinitionName": "AUTO_INVOICING_OFF",
"auditLogs": []
}
]
Query Parameters
Name | Type | Required | Default | Description |
---|---|---|---|---|
includedDeleted | boolean | false | false | choose true to include deleted tags |
audit | string | false | "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 account
This API removes a list of tags attached to an account.
HTTP Request
DELETE http://127.0.0.1:8080/1.0/kb/accounts/{accountId}/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/accounts/2ad52f53-85ae-408a-9879-32a7e59dd03d/tags?tagDef=00000000-0000-0000-0000-000000000002"
import org.killbill.billing.client.api.gen.AccountApi;
protected AccountApi accountApi;
UUID accountId = UUID.fromString("e659f0f3-745c-46d5-953c-28fe9282fc7d");
UUID autoPayOffId = UUID.fromString("00000000-0000-0000-0000-000000000001");
accountApi.deleteAccountTags(accountId,
List.of(autoPayOffId),
requestOptions);
tag_name = 'TEST'
account.remove_tag(tag_name,
user,
reason,
comment,
options)
accountApi = killbill.api.AccountApi()
account_id = 'b0da8392-49ba-43f2-8fac-3f9f85b8ff61'
tag = ["00000000-0000-0000-0000-000000000002"]
accountApi.delete_account_tags(account_id,
created_by,
api_key,
api_secret,
tag_def=tag)
Example Response:
no content
Query Parameters
Name | Type | Required | Default | Description |
---|---|---|---|---|
tagDef | array of string | true | 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.
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 audit logs
Retrieve a list of audit log records showing events that occurred involving changes to any resource associated with the specified account. History information (a copy of the full resource object) is not included.
HTTP Request
GET http://127.0.0.1:8080/1.0/kb/accounts/{accountId}/auditLogs
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/accounts/2ad52f53-85ae-408a-9879-32a7e59dd03d/auditLogs"
import org.killbill.billing.client.api.gen.AccountApi;
protected AccountApi accountApi;
UUID accountId = UUID.fromString("e9432491-6558-4007-85ef-cdae171d240c");
AuditLogs auditLogsJson = accountApi.getAccountAuditLogs(accountId,
requestOptions);
accountApi = killbill.api.AccountApi()
account_id = '4e4d8acd-c97d-447a-814b-28f995a9106c'
accountApi.get_account_audit_logs(account_id, api_key, api_secret)
account.audit(options)
Example Response:
[
{
"changeType": "INSERT",
"changeDate": "2018-07-17T15:02:45.000Z",
"objectType": "ACCOUNT",
"objectId": "2ad52f53-85ae-408a-9879-32a7e59dd03d",
"changedBy": "demo",
"reasonCode": "demo",
"comments": "demo",
"userToken": "bca75b40-ffa3-41f8-9fde-06f83ee303e8",
"history": null
},
{
"changeType": "UPDATE",
"changeDate": "2018-07-17T18:46:47.000Z",
"objectType": "ACCOUNT",
"objectId": "2ad52f53-85ae-408a-9879-32a7e59dd03d",
"changedBy": "demo",
"reasonCode": "demo",
"comments": "demo",
"userToken": "9a61a1e6-78f3-43d3-addf-e7ada180b23d",
"history": null
},
{
"changeType": "UPDATE",
"changeDate": "2018-07-17T18:48:37.000Z",
"objectType": "ACCOUNT",
"objectId": "2ad52f53-85ae-408a-9879-32a7e59dd03d",
"changedBy": "demo",
"reasonCode": "demo",
"comments": "demo",
"userToken": "0c41a04d-4037-4fa9-af71-dfe54af4d3ae",
"history": null
},
{
"changeType": "INSERT",
"changeDate": "2018-07-17T19:07:25.000Z",
"objectType": "CUSTOM_FIELD",
"objectId": "48e24ca0-1cfe-41c3-85e7-0ff0d51679fe",
"changedBy": "demo",
"reasonCode": "demo",
"comments": "demo",
"userToken": "c9b9ab11-14b1-41b5-8371-1c425f273336",
"history": null
},
{
"changeType": "UPDATE",
"changeDate": "2018-07-17T19:26:46.000Z",
"objectType": "CUSTOM_FIELD",
"objectId": "48e24ca0-1cfe-41c3-85e7-0ff0d51679fe",
"changedBy": "demo",
"reasonCode": "demo",
"comments": "demo",
"userToken": "fd26b216-deb2-43d4-b748-dec8e9917ada",
"history": null
},
{
"changeType": "DELETE",
"changeDate": "2018-07-17T20:02:01.000Z",
"objectType": "CUSTOM_FIELD",
"objectId": "48e24ca0-1cfe-41c3-85e7-0ff0d51679fe",
"changedBy": "demo",
"reasonCode": "demo",
"comments": "demo",
"userToken": "0d5c8db7-974f-47e0-9332-5d9625f72155",
"history": null
}
]
Query Parameters
None.
Response
If successful, returns a status code of 200 and a list of audit logs.
Retrieve account audit logs with history
Retrieve a list of audit log records showing events that occurred involving changes to the specified account itself. History information (a copy of the full account object) is included with each record.
HTTP Request
GET http://127.0.0.1:8080/1.0/kb/accounts/{accountId}/auditLogsWithHistory
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/accounts/2ad52f53-85ae-408a-9879-32a7e59dd03d/auditLogsWithHistory"
import org.killbill.billing.client.api.gen.AccountApi;
protected AccountApi accountApi;
UUID accountId = UUID.fromString("ecbff3be-3cbf-4e1d-ae05-d323d4597877");
List<AuditLog> auditLogWithHistories = accountApi.getAccountAuditLogsWithHistory(accountId,
requestOptions);
accountApi = killbill.api.AccountApi()
account_id = 'c62d5f6d-0b57-444d-bf9b-dd23e781fbda'
accountApi.get_account_audit_logs_with_history(account_id, api_key, api_secret)
account.audit_logs_with_history(options)
Example Response:
[
{
"changeType": "INSERT",
"changeDate": "2018-07-17T15:02:45.000Z",
"objectType": "ACCOUNT",
"objectId": "2ad52f53-85ae-408a-9879-32a7e59dd03d",
"changedBy": "demo",
"reasonCode": "demo",
"comments": "demo",
"userToken": "bca75b40-ffa3-41f8-9fde-06f83ee303e8",
"history": {
"id": null,
"createdDate": "2018-07-17T15:02:45.000Z",
"updatedDate": "2018-07-17T15:02:45.000Z",
"recordId": 120,
"accountRecordId": 120,
"tenantRecordId": 101,
"externalKey": "2ad52f53-85ae-408a-9879-32a7e59dd03d",
"email": "john@laposte.com",
"name": "John Doe",
"firstNameLength": null,
"currency": "USD",
"parentAccountId": null,
"isPaymentDelegatedToParent": null,
"billingCycleDayLocal": 0,
"paymentMethodId": null,
"referenceTime": "2018-07-17T15:02:45.000Z",
"timeZone": "UTC",
"locale": null,
"address1": null,
"address2": null,
"companyName": null,
"city": null,
"stateOrProvince": null,
"country": null,
"postalCode": null,
"phone": null,
"notes": null,
"migrated": null,
"tableName": "ACCOUNT",
"historyTableName": "ACCOUNT_HISTORY"
}
},
{
"changeType": "UPDATE",
"changeDate": "2018-07-17T18:46:47.000Z",
"objectType": "ACCOUNT",
"objectId": "2ad52f53-85ae-408a-9879-32a7e59dd03d",
"changedBy": "demo",
"reasonCode": "demo",
"comments": "demo",
"userToken": "9a61a1e6-78f3-43d3-addf-e7ada180b23d",
"history": {
"id": null,
"createdDate": "2018-07-17T18:46:47.000Z",
"updatedDate": "2018-07-17T18:46:47.000Z",
"recordId": 120,
"accountRecordId": 120,
"tenantRecordId": 101,
"externalKey": "2ad52f53-85ae-408a-9879-32a7e59dd03d",
"email": "john@laposte.com",
"name": "Another Name",
"firstNameLength": null,
"currency": "USD",
"parentAccountId": null,
"isPaymentDelegatedToParent": false,
"billingCycleDayLocal": 0,
"paymentMethodId": null,
"referenceTime": "2018-07-17T15:02:45.000Z",
"timeZone": "UTC",
"locale": null,
"address1": null,
"address2": null,
"companyName": null,
"city": null,
"stateOrProvince": null,
"country": null,
"postalCode": null,
"phone": null,
"notes": null,
"migrated": null,
"tableName": "ACCOUNT",
"historyTableName": "ACCOUNT_HISTORY"
}
},
{
"changeType": "UPDATE",
"changeDate": "2018-07-17T18:48:37.000Z",
"objectType": "ACCOUNT",
"objectId": "2ad52f53-85ae-408a-9879-32a7e59dd03d",
"changedBy": "demo",
"reasonCode": "demo",
"comments": "demo",
"userToken": "0c41a04d-4037-4fa9-af71-dfe54af4d3ae",
"history": {
"id": null,
"createdDate": "2018-07-17T18:48:37.000Z",
"updatedDate": "2018-07-17T18:48:37.000Z",
"recordId": 120,
"accountRecordId": 120,
"tenantRecordId": 101,
"externalKey": "2ad52f53-85ae-408a-9879-32a7e59dd03d",
"email": "john@laposte.com",
"name": "John Doe",
"firstNameLength": null,
"currency": "USD",
"parentAccountId": null,
"isPaymentDelegatedToParent": false,
"billingCycleDayLocal": 0,
"paymentMethodId": null,
"referenceTime": "2018-07-17T15:02:45.000Z",
"timeZone": "UTC",
"locale": null,
"address1": null,
"address2": null,
"companyName": null,
"city": null,
"stateOrProvince": null,
"country": null,
"postalCode": null,
"phone": null,
"notes": null,
"migrated": null,
"tableName": "ACCOUNT",
"historyTableName": "ACCOUNT_HISTORY"
}
}
]
Query Parameters
None.
Response
If successful, returns a status code of 200 and a list of audit logs.
Retrieve account email audit logs with history
Retrieve a list of audit log records showing events that occurred involving changes to a specified account email. History information (a copy of the full email object) is included with each record.
HTTP Request
GET http://127.0.0.1:8080/1.0/kb/accounts/{accountId}/emails/{accountEmailId}/auditLogsWithHistory
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/accounts/2ad52f53-85ae-408a-9879-32a7e59dd03d/emails/aa2a5614-88d9-4ec3-a042-a4771bd66670/auditLogsWithHistory"
import org.killbill.billing.client.api.gen.AccountApi;
protected AccountApi accountApi;
UUID accountId = UUID.fromString("873c26ef-a3fa-4942-b2f5-549b51f20b1a");
UUID accountEmailId = UUID.fromString("f637441d-855e-4bf5-bac1-6426bdb116d6");
List<AuditLog> result = accountApi.getAccountEmailAuditLogsWithHistory(accountId,
accountEmailId,
requestOptions);
accountApi = killbill.api.AccountApi()
account_id = 'c62d5f6d-0b57-444d-bf9b-dd23e781fbda'
account_email_id = 'bb390282-6757-4f4f-8dd5-456abd9f30b2'
accountApi.get_account_email_audit_logs_with_history(account_id,
account_email_id,
api_key,
api_secret)
account_email_id = 'a4627e89-a73b-4167-a7ba-92a2881eb3c4'
account.email_audit_logs_with_history(account_email_id, options)
Example Response:
[
{
"changeType": "INSERT",
"changeDate": "2018-07-18T15:13:22.000Z",
"objectType": "ACCOUNT_EMAIL",
"objectId": "aa2a5614-88d9-4ec3-a042-a4771bd66670",
"changedBy": "demo",
"reasonCode": "demo",
"comments": "demo",
"userToken": "927546eb-3431-4bcf-8fcc-1787d2130772",
"history": {
"id": null,
"createdDate": "2018-07-18T15:13:22.000Z",
"updatedDate": "2018-07-18T15:13:22.000Z",
"recordId": 1,
"accountRecordId": 120,
"tenantRecordId": 101,
"accountId": "2ad52f53-85ae-408a-9879-32a7e59dd03d",
"email": "email@laposte.com",
"isActive": true,
"tableName": "ACCOUNT_EMAIL",
"historyTableName": "ACCOUNT_EMAIL_HISTORY"
}
}
]
Query Parameters
None.
Response
If successful, returns a status code of 200 and a list of account email audit records, including history (copies of the complete record).
Retrieve blocking state audit logs with history
Retrieves the audit logs for a specific blocking state, given the blocking state id. History records (blocking state objects) are included.
HTTP Request
GET http://127.0.0.1:8080/1.0/kb/accounts/block/{blockingId}/auditLogsWithHistory
See section Account Blocking State for an introduction to blocking states.
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/accounts/block/763fd113-1b9b-4d0d-be01-6ee56d3879f5/auditLogsWithHistory"
import org.killbill.billing.client.api.gen.AccountApi;
protected AccountApi accountApi;
UUID blockingId = UUID.fromString("0997b953-2b3a-4dc5-ad01-c38911662923");
AuditLogs result = accountApi.getBlockingStateAuditLogsWithHistory(blockingId, requestOptions);
Example Response:
[
{
"changeType": "INSERT",
"changeDate": "2019-02-22T22:38:10.000Z",
"objectType": "BLOCKING_STATES",
"objectId": "763fd113-1b9b-4d0d-be01-6ee56d3879f5",
"changedBy": "admin",
"reasonCode": null,
"comments": null,
"userToken": "1f03e074-dea1-45c5-aee3-c9464886f476",
"history": {
"id": null,
"createdDate": "2019-02-22T22:38:10.000Z",
"updatedDate": "2019-02-22T22:38:10.000Z",
"recordId": 1326,
"accountRecordId": 10,
"tenantRecordId": 1,
"blockableId": "70b6856e-6938-495f-9ae9-0a8ec0571c37",
"type": "SUBSCRIPTION",
"state": "ENT_STARTED",
"service": "entitlement-service",
"blockChange": false,
"blockEntitlement": false,
"blockBilling": false,
"effectiveDate": "2019-02-22T22:38:10.000Z",
"isActive": true,
"tableName": "BLOCKING_STATES",
"historyTableName": "BLOCKING_STATES",
"active": true
}
}
]
Query Parameters
None.
Response
If successful, returns a status code of 200 and a list of blocking state audit logs with history.
Retrieve account timeline
This API retrieves the chronological set of events that occurred concerning a specific Account
.
HTTP Request
GET http://127.0.0.1:8080/1.0/kb/accounts/{accountId}/timeline
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/accounts/2ad52f53-85ae-408a-9879-32a7e59dd03d/timeline"
import org.killbill.billing.client.api.gen.AccountApi;
protected AccountApi accountApi;
UUID accountId = UUID.fromString("16364ac4-2a77-4444-b2d8-e980c37a8954");
Boolean parallel = false;
AccountTimeline timeline = accountApi.getAccountTimeline(accountId,
parallel,
AuditLevel.NONE,
requestOptions);
account_id = account.account_id
audit = 'MINIMAL'
KillBillClient::Model::AccountTimeline.timeline(account_id,
audit,
options)
accountApi = killbill.api.AccountApi()
account_id = '43488882-1777-460c-bc32-e375e67d09cf'
accountApi.get_account_timeline(account_id, api_key, api_secret)
Example Response:
{
"account": {
"accountId": "2ad52f53-85ae-408a-9879-32a7e59dd03d",
"name": "John Doe",
"firstNameLength": null,
"externalKey": "2ad52f53-85ae-408a-9879-32a7e59dd03d",
"email": "john@laposte.com",
"billCycleDayLocal": 0,
"currency": "USD",
"parentAccountId": null,
"isPaymentDelegatedToParent": false,
"paymentMethodId": null,
"referenceTime": "2018-07-17T15:02:45.000Z",
"timeZone": "UTC",
"address1": null,
"address2": null,
"postalCode": null,
"company": null,
"city": null,
"state": null,
"country": null,
"locale": null,
"phone": null,
"notes": null,
"isMigrated": null,
"accountBalance": null,
"accountCBA": null,
"auditLogs": []
},
"bundles": [],
"invoices": [],
"payments": []
}
Query Parameters
Name | Type | Required | Default | Description |
---|---|---|---|---|
audit | string | false | "NONE" | Level of audit information to return: "NONE", "MINIMAL", or "FULL" |
Response
If successful, returns a status code of 200 and a complete account record including: the account object; bundles with subscriptions and timelines giving all events; invoices; and payments including payment attempts.
Payment Method
Payment Method Resource
The Payment Method
resource represents the payment methods associated with a customer Account
. There are two parts to the state associated with this resource, a first generic set of attributes kept by Kill Bill core subsystem, and another set of attributes kept at the (payment) plugin level.
- The core Kill Bill attributes shown below mostly track the associated payment plugin that is used to interact with the payment gateway.
- The plugin attributes are typically the details about such customer payment method: In the case of a credit card for instance, the plugin would keep track of things like
name
,address
,last4
, andtoken
. Not only are such attributes dependent on the payment method, but they are also dependent on the third party payment gateway, and on the tokenization model, which is why they are kept by the plugin (internal tables), and not by the Kill Bill core payment subsystem.
Kill Bill also supports a more advanced use case for payment routing, where the choice of the payment gateway is decided at run time based on custom business rules. Additional information can be found in our Payment Manual.
The Kill Bill attributes are the following:
Name | Type | Generated by | Description |
---|---|---|---|
paymentMethodId | string | system | UUID for this payment method |
externalKey | string | user | Optional external key provided by the client |
accountId | string | system | UUID for the associated account |
isDefault | boolean | user | Indicates whether this is the default payment method |
pluginName | string | user | Name of the associated plugin. |
pluginInfo | string | user | Plugin specific information, as required. |
All payment operations associated with this payment method will be delegated to the plugin specified by pluginName.
Payment Methods
Basic operations to retrieve, list, search and delete payment methods.
Note that the creation of a payment method needs to be done at the Account level using the Add a payment method endpoint. The pluginName
attribute identifies the payment plugin that will be used by the system when this payment method is used for a payment.
Retrieve a payment method by id
Retrieve information on a payment method, given its payment method ID.
HTTP Request
GET http://127.0.0.1:8080/1.0/kb/paymentMethods/{paymentMethodId}
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/paymentMethods/916619a4-02bb-4d3d-b3da-2584ac897b19'
import org.killbill.billing.client.api.gen.PaymentMethodApi;
protected PaymentMethodApi paymentMethodApi;
UUID paymentMethodId = UUID.fromString("3c449da6-7ec4-4c74-813f-f5055739a0b9");
Boolean includedDeleted = false; // Will not include deleted
Boolean withPluginInfo = true; // Will include plugin info
Map<String, String> NULL_PLUGIN_PROPERTIES = null;
PaymentMethod paymentMethodJson = paymentMethodApi.getPaymentMethod(paymentMethodId,
includedDeleted,
withPluginInfo,
NULL_PLUGIN_PROPERTIES,
AuditLevel.NONE,
requestOptions);
payment_method_id = "6a0bf13e-d57f-4f79-84bd-3690135f1923"
with_plugin_info = false
KillBillClient::Model::PaymentMethod.find_by_id(payment_method_id,
with_plugin_info,
options)
paymentMethodApi = killbill.api.PaymentMethodApi()
payment_method_id = '0052cddd-0f61-4f68-b653-ca49b5d7f915'
paymentMethodApi.get_payment_method(payment_method_id, api_key, api_secret)
Example Response:
# Subset of headers returned when specifying -v curl option
< HTTP/1.1 200 OK
<
{
"paymentMethodId":"916619a4-02bb-4d3d-b3da-2584ac897b19",
"externalKey":"coolPaymentMethod",
"accountId":"84c7e0d4-a5ed-405f-a655-3ed16ae19997",
"isDefault":false,
"pluginName":"__EXTERNAL_PAYMENT__",
"pluginInfo":null,
"auditLogs":[]
}
class PaymentMethod {
org.killbill.billing.client.model.gen.PaymentMethod@c789046
paymentMethodId: 3c449da6-7ec4-4c74-813f-f5055739a0b9
externalKey: 7c13b1fb-5fa5-49cb-bbb6-50b0fa78a988
accountId: 2b995dde-ce30-451f-8bbf-5bb9ed312505
isDefault: true
pluginName: noop
pluginInfo: class PaymentMethodPluginDetail {
externalPaymentMethodId: afcdfd42-1bad-4caf-86be-93a27da51c55
isDefaultPaymentMethod: false
properties: [class PluginProperty {
key: CC_NAME
value: Bozo
isUpdatable: false
}, class PluginProperty {
key: CC_CITY
value: SF
isUpdatable: false
}, class PluginProperty {
key: CC_LAST_4
value: 4365
isUpdatable: false
}, class PluginProperty {
key: CC_STATE
value: CA
isUpdatable: false
}, class PluginProperty {
key: CC_COUNTRY
value: Zimbawe
isUpdatable: false
}]
}
auditLogs: []
}
{
"paymentMethodId":"6a0bf13e-d57f-4f79-84bd-3690135f1923",
"externalKey":"unknown",
"accountId":"f9c4801f-0daa-4c46-bea0-59490d07fc5e",
"isDefault":false,
"pluginName":"__EXTERNAL_PAYMENT__",
"pluginInfo":{
"properties":[]
},
"auditLogs":[]
}
{'account_id': '9f2f95b9-7021-4645-9863-30feac25841a',
'audit_logs': [],
'external_key': 'unknown',
'is_default': False,
'payment_method_id': '0052cddd-0f61-4f68-b653-ca49b5d7f915',
'plugin_info': None,
'plugin_name': '__EXTERNAL_PAYMENT__'}
Query Parameters
Name | Type | Required | Default | Description |
---|---|---|---|---|
includedDeleted | boolean | no | false | If true, include deleted payment methods |
withPluginInfo | boolean | no | false | If true, include plugin info |
audit | string | no | "NONE" | Level of audit information to return |
If withPluginInfo is set to true, attributes for the active plugin are returned. These are plugin-dependent (see discussion above). Audit information options are "NONE", "MINIMAL" (only inserts), or "FULL".
Response
If successful, returns a status code of 200 and a payment method resource object.
Retrieve a payment method by external key
HTTP Request
GET http://127.0.0.1:8080/1.0/kb/paymentMethods
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/paymentMethods/916619a4-02bb-4d3d-b3da-2584ac897b19?externalKey=coolPaymentMethod'
import org.killbill.billing.client.api.gen.PaymentMethodApi;
protected PaymentMethodApi paymentMethodApi;
String externalKey = "foo";
Boolean includedDeleted = false; // Will not include deleted
Boolean withPluginInfo = false; // Will not reflect plugin info
Map<String, String> NULL_PLUGIN_PROPERTIES = null;
PaymentMethod paymentMethod = paymentMethodApi.getPaymentMethodByKey(externalKey,
includedDeleted,
withPluginInfo,
NULL_PLUGIN_PROPERTIES,
AuditLevel.NONE,
requestOptions);
payment_method_ek = "sample_external_key"
included_deleted = false
with_plugin_info = false
audit = 'NONE'
KillBillClient::Model::PaymentMethod.find_by_external_key(payment_method_ek,
included_deleted,
with_plugin_info,
audit,
options)
paymentMethodApi = killbill.api.PaymentMethodApi()
external_key = 'sample_external_key'
paymentMethodApi.get_payment_method_by_key(external_key, api_key, api_secret)
Example Response:
# Subset of headers returned when specifying -v curl option
< HTTP/1.1 200 OK
<
{
"paymentMethodId":"916619a4-02bb-4d3d-b3da-2584ac897b19",
"externalKey":"coolPaymentMethod",
"accountId":"84c7e0d4-a5ed-405f-a655-3ed16ae19997",
"isDefault":false,
"pluginName":"__EXTERNAL_PAYMENT__",
"pluginInfo":null,
"auditLogs":[]
}
class PaymentMethod {
org.killbill.billing.client.model.gen.PaymentMethod@360d34cd
paymentMethodId: c46dbe85-a14b-4d5b-8b0d-e6a07b7ff111
externalKey: foo
accountId: dae298f7-62b0-4774-a213-92f968693cdc
isDefault: true
pluginName: noop
pluginInfo: null
auditLogs: []
}
{
"paymentMethodId":"4307ac7c-04a7-41e1-9cb0-8a4d4420104c",
"externalKey":"sample_external_key",
"accountId":"aba041a0-52f3-4d0d-b8e0-dec442dbc51e",
"isDefault":true,
"pluginName":"__EXTERNAL_PAYMENT__",
"pluginInfo":{
"properties":[]
},
"auditLogs":[]
}
{'account_id': '1d1c63ae-fd71-4e0c-87d4-24a334335c49',
'audit_logs': [],
'external_key': 'sample_external_key',
'is_default': False,
'payment_method_id': '882b2fa0-5946-487a-933c-b2572ea4383c',
'plugin_info': None,
'plugin_name': '__EXTERNAL_PAYMENT__'}
Query Parameters
Name | Type | Required | Default | Description |
---|---|---|---|---|
externalKey | string | yes | none | External key |
includedDeleted | boolean | no | false | If true, include deleted payment methods |
withPluginInfo | boolean | no | false | If true, include plugin info |
audit | string | no | "NONE" | Level of audit information to return |
If withPluginInfo is set to true, attributes for the active plugin are returned. These are plugin-dependent (see discussion above). Audit information options are "NONE", "MINIMAL" (only inserts), or "FULL".
Response
If successful, returns a status code of 200 and a payment method resource object.
Delete a payment method
This API deletes a payment method. The default payment method may not be deleted, depending on the query parameters.
HTTP Request
DELETE http://127.0.0.1:8080/1.0/kb/paymentMethods/{paymentMethodId}
Example Request:
curl -v \
-X DELETE \
-u admin:password \
-H 'X-Killbill-ApiKey: bob' \
-H 'X-Killbill-ApiSecret: lazar' \
-H 'X-Killbill-CreatedBy: demo' \
'http://127.0.0.1:8080/1.0/kb/paymentMethods/916619a4-02bb-4d3d-b3da-2584ac897b19'
import org.killbill.billing.client.api.gen.PaymentMethodApi;
protected PaymentMethodApi paymentMethodApi;
UUID paymentMethodId = UUID.fromString("3c449da6-7ec4-4c74-813f-f5055739a0b9");
Boolean deleteDefaultPmWithAutoPayOff = true; // Will delete default payment method with auto pay off
Boolean forceDefaultPmDeletion = true; // Will force default payment method deletion
Map<String, String> NULL_PLUGIN_PROPERTIES = null;
paymentMethodApi.deletePaymentMethod(paymentMethodId,
deleteDefaultPmWithAutoPayOff,
forceDefaultPmDeletion,
NULL_PLUGIN_PROPERTIES,
requestOptions);
payment_method_id = "4307ac7c-04a7-41e1-9cb0-8a4d4420104c"
set_auto_pay_off = false
force_default_deletion = false
KillBillClient::Model::PaymentMethod.destroy(payment_method_id,
set_auto_pay_off,
force_default_deletion,
user,
reason,
comment,
options)
paymentMethodApi = killbill.api.PaymentMethodApi()
payment_method_id = '0052cddd-0f61-4f68-b653-ca49b5d7f915'
paymentMethodApi.delete_payment_method(payment_method_id,
created_by,
api_key,
api_secret)
Example Response:
# Subset of headers returned when specifying -v curl option
< HTTP/1.1 204 No Content
< Content-Type: application/json
< Content-Length: 0
no content
no content
no content
Query Parameters
Name | Type | Required | Default | Description |
---|---|---|---|---|
deleteDefaultPmWithAutoPayOff | boolean | no | false | if true, delete default payment method only if AUTO_PAY_OFF is set |
forceDefaultPmDeletion | boolean | no | false | if true, force default payment method deletion |
The query parameters determine the behavior if the payment method specified is the default method: If forceDefaultPmDeletion is true, the payment method will be deleted unconditionally. If deleteDefaultPmWithAutoPayOff is true, the payment method will also be deleted, and AUTO_PAY_OFF will be set (if not already). If neither parameter is true, the default payment method will not be deleted (the call will fail).
Response
If successful, returns a status code of 204 and an empty body. If the payment method is the default and cannot be deleted, an error code of 500 and a suitable message will be returned.
List and Search
These endpoints provide the ability to list and search for payment methods for a specific tenant
List payment methods
List all payment methods stored for the accounts maintained by this tenant
HTTP Request
GET http://127.0.0.1:8080/1.0/kb/paymentMethods/pagination
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/paymentMethods/pagination'
import org.killbill.billing.client.api.gen.PaymentMethodApi;
protected PaymentMethodApi paymentMethodApi;
Long offset = 0L;
Long limit = 1L;
String pluginName = null;
Boolean withPluginInfo = false;
Map<String, String> NULL_PLUGIN_PROPERTIES = null;
PaymentMethods allPaymentMethods = paymentMethodApi.getPaymentMethods(offset,
limit,
pluginName,
withPluginInfo,
NULL_PLUGIN_PROPERTIES,
AuditLevel.NONE,
requestOptions);
offset = 0
limit = 100
payment_method.find_in_batches(offset,
limit,
options)
paymentMethodApi = killbill.api.PaymentMethodApi()
paymentMethodApi.get_payment_methods(api_key, api_secret)
Example Response:
# Subset of headers returned when specifying -v curl option
< HTTP/1.1 200 OK
<
[
{
"paymentMethodId": "916619a4-02bb-4d3d-b3da-2584ac897b19",
"externalKey": "coolPaymentMethod",
"accountId": "84c7e0d4-a5ed-405f-a655-3ed16ae19997",
"isDefault": false,
"pluginName": "__EXTERNAL_PAYMENT__",
"pluginInfo": null,
"auditLogs": []
},
{
"paymentMethodId": "dc89832d-18a3-42fd-b3be-cac074fddb36",
"externalKey": "paypal",
"accountId": "ca15adc4-1061-4e54-a9a0-15e773b3b154",
"isDefault": false,
"pluginName": "killbill-paypal-express",
"pluginInfo": null,
"auditLogs": []
}
]
//First element of the list
class PaymentMethod {
org.killbill.billing.client.model.gen.PaymentMethod@3b058e2d
paymentMethodId: 98420efb-142f-4437-9a93-817ded413313
externalKey: e78ae144-8727-46f4-8cf2-63636813f232
accountId: 73f59eee-abec-4d3f-ab62-21dba663bd25
isDefault: true
pluginName: noop
pluginInfo: null
auditLogs: []
}
[
{
"paymentMethodId":"6a0bf13e-d57f-4f79-84bd-3690135f1923",
"externalKey":"unknown",
"accountId":"f9c4801f-0daa-4c46-bea0-59490d07fc5e",
"isDefault":false,
"pluginName":"__EXTERNAL_PAYMENT__",
"pluginInfo":{
"properties":[]
},
"auditLogs":[]
}
]
[{'account_id': '5d82791d-c47f-4c4b-be11-b68233656b96',
'audit_logs': [],
'external_key': 'unknown',
'is_default': False,
'payment_method_id': '06955087-e191-4da5-99c9-e712b21f6aa6',
'plugin_info': None,
'plugin_name': '__EXTERNAL_PAYMENT__'}]
Query Parameters
Name | Type | Required | Default | Description |
---|---|---|---|---|
offset | long | no | 0 | Starting position in list |
limit | long | no | 100 | Max number of items to return |
withPluginInfo | boolean | no | false | If true, include plugin info |
pluginName | string | no | all plugins | If present, list only payment methods that use this plugin |
pluginProperties | array of strings | no | no properties | return these properties for this plugin |
audit | string | no | "NONE" | Level of audit information to return |
If withPluginInfo is set to true, attributes for each payment method's plugin are returned. These are plugin-dependent (see discussion above). If pluginName is given, list only payment methods that use this plugin, and return only the attributes specified by pluginProperties. Audit information options are "NONE", "MINIMAL" (only inserts), or "FULL".
Response
If successful, returns a status code of 200 and a list of payment method resource objects.
Search payment methods
This API searches all payment methods for a specified search string. The search string is given as a path parameter.
HTTP Request
GET http://127.0.0.1:8080/1.0/kb/paymentMethods/search/{searchKey}
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/paymentMethods/search/coolPaymentMethod'
import org.killbill.billing.client.api.gen.PaymentMethodApi;
protected PaymentMethodApi paymentMethodApi;
String searchKey = "4365";
Long offset = 0L;
Long limit = 100L;
String pluginName = null;
Boolean withPluginInfo = true;
Map<String, String> NULL_PLUGIN_PROPERTIES = null;
List<PaymentMethod> results = paymentMethodApi.searchPaymentMethods(searchKey,
offset,
limit,
pluginName,
withPluginInfo,
NULL_PLUGIN_PROPERTIES,
AuditLevel.NONE,
requestOptions);
search_key = 'example'
offset = 0
limit = 100
payment_method.find_in_batches_by_search_key(search_key,
offset,
limit,
options)
paymentMethodApi = killbill.api.PaymentMethodApi()
search_key = '__EXTERNAL_PAYMENT__'
paymentMethodApi.search_payment_methods(search_key, api_key, api_secret)
Example Response:
# Subset of headers returned when specifying -v curl option
< HTTP/1.1 200 OK
<
[
{
"paymentMethodId": "916619a4-02bb-4d3d-b3da-2584ac897b19",
"externalKey": "coolPaymentMethod",
"accountId": "84c7e0d4-a5ed-405f-a655-3ed16ae19997",
"isDefault": false,
"pluginName": "__EXTERNAL_PAYMENT__",
"pluginInfo": null,
"auditLogs": []
}
]
//First element of the list
class PaymentMethod {
org.killbill.billing.client.model.gen.PaymentMethod@6b40b41a
paymentMethodId: 62c434f7-41fe-497d-8fb0-c35bb6706180
externalKey: 4ac4162a-ae9c-48ca-bb43-8a4bcd6c2717
accountId: a6941a79-8b7b-4da7-99e0-bffc3d549f87
isDefault: true
pluginName: noop
pluginInfo: class PaymentMethodPluginDetail {
externalPaymentMethodId: 9ddcce2d-b65f-4e08-8006-1395e47ba97a
isDefaultPaymentMethod: false
properties: [class PluginProperty {
key: CC_NAME
value: Bozo
isUpdatable: false
}, class PluginProperty {
key: CC_CITY
value: SF
isUpdatable: false
}, class PluginProperty {
key: CC_LAST_4
value: 4365
isUpdatable: false
}, class PluginProperty {
key: CC_STATE
value: CA
isUpdatable: false
}, class PluginProperty {
key: CC_COUNTRY
value: Zimbawe
isUpdatable: false
}]
}
auditLogs: []
}
[
{
"paymentMethodId":"6a0bf13e-d57f-4f79-84bd-3690135f1923",
"externalKey":"unknown",
"accountId":"f9c4801f-0daa-4c46-bea0-59490d07fc5e",
"isDefault":false,
"pluginName":"__EXTERNAL_PAYMENT__",
"pluginInfo":{
"properties":[]
},
"auditLogs":[]
}
]
[{'account_id': '81d8b04d-dee1-49bf-bc73-48219df21af9',
'audit_logs': [],
'external_key': 'unknown',
'is_default': False,
'payment_method_id': 'bcecaf3f-16c7-4d65-aed0-b08cc5e34a6b',
'plugin_info': None,
'plugin_name': '__EXTERNAL_PAYMENT__'}]
Query Parameters
Name | Type | Required | Default | Description |
---|---|---|---|---|
offset | long | no | 0 | Starting position in list |
limit | long | no | 100 | Max number of items to return |
withPluginInfo | boolean | no | false | If true, include plugin info |
pluginName | string | no | all plugins | If present, list only payment methods that use this plugin |
pluginProperties | array of strings | no | no properties | return these properties for this plugin |
audit | string | no | "NONE" | Level of audit information to return |
If withPluginInfo is set to true, attributes for each payment method's plugin are returned. These are plugin-dependent (see discussion above). If pluginName is given, list only payment methods that use this plugin, and return only the attributes specified by pluginProperties. Audit information options are "NONE", "MINIMAL" (only inserts), or "FULL".
Response
If successful, returns a status code of 200 and a list of payment method resource objects that match the search key.
Custom Fields
Custom fields
are {key, value}
attributes that can be attached to any customer resources. For more on custom fields see Custom Fields. These endpoints manage custom fields associated with PaymentMethod
objects.
Add custom fields to a payment method
Adds one or more custom fields to a payment method object. Existing custom fields are not disturbed.
HTTP Request
POST http://127.0.0.1:8080/1.0/kb/paymentMethods/{paymentMethodId}/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 'X-Killbill-CreatedBy: demo' \
-d '[{
"objectId": "916619a4-02bb-4d3d-b3da-2584ac897b19",
"objectType": "PAYMENT_METHOD",
"name": "Test Custom Field",
"value": "test_value"
}]' \
'http://127.0.0.1:8080/1.0/kb/paymentMethods/916619a4-02bb-4d3d-b3da-2584ac897b19/customFields'
import org.killbill.billing.client.api.gen.PaymentMethodApi;
protected PaymentMethodApi paymentMethodApi;
UUID paymentMethodId = UUID.fromString("3c449da6-7ec4-4c74-813f-f5055739a0b9");
final List<AuditLog> EMPTY_AUDIT_LOGS = Collections.emptyList();
CustomFields customFields = new CustomFields();
customFields.add(new CustomField(null,
paymentMethodId,
ObjectType.PAYMENT_METHOD,
"Test Custom Field",
"test_value",
EMPTY_AUDIT_LOGS));
paymentMethodApi.createPaymentMethodCustomFields(paymentMethodId,
customFields,
requestOptions);
custom_field = KillBillClient::Model::CustomFieldAttributes.new
custom_field.object_type = 'PAYMENT_METHOD'
custom_field.name = 'Test Custom Field'
custom_field.value = 'test_value'
payment_method.add_custom_field(custom_field,
user,
reason,
comment,
options)
paymentMethodApi = killbill.api.PaymentMethodApi()
payment_method_id = '4927c1a2-3959-4f71-98e7-ce3ba19c92ac'
body = CustomField(name='Test Custom Field', value='test_value')
paymentMethodApi.create_payment_method_custom_fields(payment_method_id,
[body],
created_by,
api_key,
api_secret)
Example Response:
# Subset of headers returned when specifying -v curl option
< HTTP/1.1 201 Created
< Location: http://127.0.0.1:8080/1.0/kb/paymentMethods/916619a4-02bb-4d3d-b3da-2584ac897b19/customFields
< Content-Type: application/json
< Content-Length: 0
//First element of the list
class CustomField {
org.killbill.billing.client.model.gen.CustomField@c7d0c38a
customFieldId: null
objectId: 3c449da6-7ec4-4c74-813f-f5055739a0b9
objectType: PAYMENT_METHOD
name: Test Custom Field
value: test_value
auditLogs: []
}
[
{
"customFieldId":"7fb3dde7-0911-4477-99e3-69d142509bb9",
"objectId":"4927c1a2-3959-4f71-98e7-ce3ba19c92ac",
"objectType":"PAYMENT_METHOD",
"name":"Test Custom Field",
"value":"test_value",
"auditLogs":[]
}
]
no content
Request Body
A list of objects giving the name and value of the custom field, or fields, to be added. For example:
[ { "name": "CF1", "value": "123" } ]
Query Parameters
None.
Response
If successful, returns a 201 status code. In addition, a Location
header is returned giving the URL to retrieve the custom fields associated with the payment method.
Retrieve payment method custom fields
Returns any custom field objects associated with the specified payment method
HTTP Request
GET http://127.0.0.1:8080/1.0/kb/paymentMethods/{paymentMethodId}/customFields
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/paymentMethods/916619a4-02bb-4d3d-b3da-2584ac897b19/customFields'
import org.killbill.billing.client.api.gen.PaymentMethodApi;
protected PaymentMethodApi paymentMethodApi;
UUID paymentMethodId = UUID.fromString("3c449da6-7ec4-4c74-813f-f5055739a0b9");
List<CustomField> customFields = paymentMethodApi.getPaymentMethodCustomFields(paymentMethodId,
AuditLevel.NONE,
requestOptions);
audit = 'NONE'
payment_method.custom_fields(audit, options)
paymentMethodApi = killbill.api.PaymentMethodApi()
payment_method_id = '4927c1a2-3959-4f71-98e7-ce3ba19c92ac'
paymentMethodApi.get_payment_method_custom_fields(payment_method_id,
api_key,
api_secret)
Example Response:
# Subset of headers returned when specifying -v curl option
< HTTP/1.1 200 OK
<
[
{
"customFieldId": "6d4c073b-fd89-4e39-9802-eba65f42492f",
"objectId": "916619a4-02bb-4d3d-b3da-2584ac897b19",
"objectType": "PAYMENT_METHOD",
"name": "Test Custom Field",
"value": "test_value",
"auditLogs": []
}
]
//First element of the list
class CustomField {
org.killbill.billing.client.model.gen.CustomField@c7d0c38a
customFieldId: null
objectId: 3c449da6-7ec4-4c74-813f-f5055739a0b9
objectType: PAYMENT_METHOD
name: Test Custom Field
value: test_value
auditLogs: []
}
[
{
"customFieldId":"7fb3dde7-0911-4477-99e3-69d142509bb9",
"objectId":"4927c1a2-3959-4f71-98e7-ce3ba19c92ac",
"objectType":"PAYMENT_METHOD",
"name":"Test Custom Field",
"value":"test_value",
"auditLogs":[]
}
]
[{'audit_logs': [],
'custom_field_id': '5670b594-9317-4aeb-bfef-2c2342ec172a',
'name': 'Test Custom Field',
'object_id': '4927c1a2-3959-4f71-98e7-ce3ba19c92ac',
'object_type': 'PAYMENT_METHOD',
'value': 'test_value'}]
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 payment method
Modifies the value of one or more existing custom fields associated with a payment object
HTTP Request
PUT http://127.0.0.1:8080/1.0/kb/paymentMethods/{paymentMethodId}/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 'X-Killbill-CreatedBy: demo' \
-d '[{
"customFieldId": "6d4c073b-fd89-4e39-9802-eba65f42492f",
"value": "NewValue"
}]' \
'http://127.0.0.1:8080/1.0/kb/paymentMethods/916619a4-02bb-4d3d-b3da-2584ac897b19/customFields'
import org.killbill.billing.client.api.gen.PaymentMethodApi;
protected PaymentMethodApi paymentMethodApi;
UUID paymentMethodId = UUID.fromString("3c449da6-7ec4-4c74-813f-f5055739a0b9");
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);
paymentMethodApi.modifyPaymentMethodCustomFields(paymentMethodId,
customFields,
requestOptions);