NAV Navbar
  • Using Kill Bill APIs
  • Tenant
  • Catalog
  • Account
  • Payment Method
  • Subscription
  • Bundle
  • Invoice
  • Credit
  • Payment
  • Payment Transaction
  • Invoice Payment
  • Usage
  • Custom Field
  • Tag
  • Tag Definition
  • Admin
  • Report a doc problem

    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 the salt 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 Accounts 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 list
    • X-Killbill-Pagination-NextOffset : The header will only be present if there are additional entries to return and would include the next offset
    • X-Killbill-Pagination-TotalNbRecords : The total number of records
    • X-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 no updates.
    • 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 core
    • killbill-plugin-api: APIs used by Kill Bill core to communicate with plugins
    • killbill-commons: Common code across modules
    • killbill-platform: Platform related code such as OSGI framework, webapp pieces
    • killbill-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 success
    • 4xx status often indicates a client side error -- e.g missing madatory API field
    • 5xx 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.xmlis 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:

    1. Use the default test catalog that ships with Kill Bill by creating a tenant with useGlobalDefault=true
    2. 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).
    3. 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.
    4. 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 planselected 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 $0 TRIAL 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
    email 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.

    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.

    Email

    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.g Account. 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 customer Account.

    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, and token. 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.

    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);