Invoice Grouping Example

127 views
Skip to first unread message

vivek rao

unread,
Mar 26, 2024, 5:04:10 AM3/26/24
to Kill Bill users mailing-list
Hello

In the API documentation there is one section about Invoice Grouping.

The link given for demo plugin is not working. Pls provide a sample plugin code which can be used as the reference to implement the grouping logic which we would need which fits our business case.
inv_group.png

Few queries about Invoice Grouping.

1. Will this plugin only split an existing invoice into multiple invoices? If yes, how the payment related to the original invoice is linked to the split invoices?

2. Can this plugin also be used to group multiple invoices(for which payments have already happened individually) into one invoice group?

we can then use it for below given case:
Set billingAlignment to BUNDLE and each bundle having a separate BCD.

Bundle-1 : BCD 1
Bundle-2 : BCD 2
Bundle-3 : BCD 3

so we would expect for each Bundle there is a separate Invoice generated on 1st, 2nd and 3rd of the month.
For viewing/reporting purpose we want to group 3 invoices into one invoice group and see it as one invoice.

Also we have observed that if BCD of any bundle is same as some other bundle then the invoice generated on the BCD is only one for both the bundles. Any way to config the system to always generate one invoice for each bundle even if BCD coincides?

3. More details about this API would be useful InvoicePluginApi#getInvoiceGrouping
  • When this API be called on any change in the invoice? similar to getAdditionalInvoiceItems?
  • What happens when there is some error encountered in this API? what would be the impact?
Thanks 
Vivek

karan bansal

unread,
Mar 26, 2024, 2:26:06 PM3/26/24
to Kill Bill users mailing-list
Hi Vivek,

The demo repo is set as private, I am checking about it internally, will update you as soon as I hear further.

The answer to both questions 1 and 2 is No, this cannot be used for existing invoices. You need to trigger the invoice group run using this api and it will be caught here within the invoice plugin, just like getAdditionalInvoiceItems is called for normal invoicing operation. For cases of failure I think you can implement the onFailureCall mentioned here

Regards
Karan

karan bansal

unread,
Mar 28, 2024, 12:13:18 PM3/28/24
to Kill Bill users mailing-list
Hi Vivek,

The demo repo for invoice grouping is public now. Feel free to use it as reference.

Regards
Karan

vivek rao

unread,
Apr 3, 2024, 4:35:58 AM4/3/24
to Kill Bill users mailing-list
Hi Karan,

Thanks for making it public.

I have gone through the details of this plugin and understood how 1 invoice can be split into N invoices(subscription level) through the invoicePlugin.getInvoiceGrouping and configure different payment methods at subscription so that payments for the original invoice can happen in parts over multiple payment methods.

1 Invoice N payments is also one of our key use case. So we will be planning to use this in our solution

inv_group_new.png
Problem-1: Invoice Grouping, Subscription Level PM_ID for IN_ADVANCE Plans
Our Catalog has plans which are IN_ADVANCE payment.
In such case as soon as the subscription is made one invoice is generated immediately having the Fixed, Recurring charge applicable for the plan, and followed by its payment using the available default payment method at the Account.

If for this subscription we wanted to configure a different payment method instead of the default one, how can that be achieved if the invoice and payment is triggered immediately at the time of subscription?
Is there any way to create the subscription is PENDING state, then configure the Payment Method for the subscription and then make the subscription ACTIVE.

Problem-2 : Why this solution cannot use for production "as is"
The description says that this plugin solution cannot be used in production "as-is". What is the reason? Does this have any functional loophole or any performance/reliability issue?
Could you please list out the points that needs to be handled in case we want to take this to production.

Thanks
Vivek

karan bansal

unread,
Apr 3, 2024, 1:29:35 PM4/3/24
to Kill Bill users mailing-list
Hi Vivek,

The only way to create the subscription with Pending status is to set the entitlement date in future, when the state automatically becomes active. 

The other way that can stop the payment from immediately firing is to either add the tag Auto_Pay_Off to the account at the time of account creation OR to add Auto_invoicing_draft ( though the grouping plugin needs to be tested for draft invoice ). 

The plugin was created for a specific usecase, however, it is open-source now. If it works as is for you, then feel free to use.

Regards
Karan

vivek rao

unread,
May 5, 2024, 11:12:54 PM5/5/24
to Kill Bill users mailing-list
Hello

Before we try to attempt this Solution in our system, could you please confirm after implementing Invoice grouping function,  will the both Invoice exists in the system? The original Invoice which had all line items of all subscriptions and Individual invoice of each subscription which got created because of grouping of line items based on subscriptions.

In the Invoice Listing API, will original Invoice and the Grouped Invoices both will be available in the response? Any way to filter either Original Inoice/Grouped Invoices from the response so that only one type of invoice exists in the response?

Our expectation is to be able view/download Consolidated Invoice(which is having all line items of all products/subscriptions) and also the Individual Invoices(which are subset(subscription level) of the main invoice).

How can this be achieved? Which API can support Listing/Viewing/Downloading original Invoice(all line items) and grouped Invoices(subscription) level.

Which fields in the invoice response can we find out it is belong with which original invoice? 

use case:
- Our company finance team will be interested in Consolidated Invoice
- Our Clients Interface team(finance team) could be different for different product Lines. For them we will have to provide the invoice which contains line items only of that product subscription.

Hope my query was clear.

Thanks
Vivek

karan bansal

unread,
May 6, 2024, 1:25:09 PM5/6/24
to Kill Bill users mailing-list
Hi Vivek,

Yes the query is clear. I believe that the invoicing group call should result in the group of invoices only and not the additional consolidated one, as mentioned in the docs here.

Regards
Karan

vivek rao

unread,
Jul 29, 2024, 12:14:42 PM7/29/24
to Kill Bill users mailing-list
Hello Karan

Today I wanted to setup and test the invoice grouping feature of KB.

I implemented the below method in my invoice plugin. I added some logs in the entry of this method.
public InvoiceGroupingResult getInvoiceGrouping(final Invoice invoice, final boolean dryRun, final Iterable<PluginProperty> properties, final InvoiceContext context)

org.killbill.payment.invoice.plugin is also set with my invoice plugin name.

For one account I triggered an invoice dryRun from KAUI, one invoice was generated, but in the logs I didn't see getInvoiceGrouping getting called.

Next I committed the dryRun Invoice hoping that the getInvoiceGrouping  will get called when invoice is getting committed. But in this case also i didn't see getInvoiceGrouping getting called.

What am I missing?

In the KB Core code there is a flag allowSplitting in the invoice flows. Anything related to this flag need to enable?

Our expectation:
In recurrence billing flow on the day of BCD when invoice gets generated automatically the invoice items must get split(based on the logic which we will implement in getInvoiceGrouping) and it should be followed by payments for each of the split invoices as per the payment method which is set by overrding.
How this can be achieved?

Thanks
Vivek

vivek rao

unread,
Jul 29, 2024, 8:38:10 PM7/29/24
to Kill Bill users mailing-list
Hello

Can someone check this and let us know whether invoice grouping function works or not?

This is a very important function for us in billing. 

Without this function we cannot go to production with KB billing solution. 

Thanks
Vivek

Shaun Forgie

unread,
Jul 29, 2024, 10:54:24 PM7/29/24
to vivek rao, Kill Bill users mailing-list
Hi Vivek,

Can I confirm your requirements?

Do you want separate invoices for each subscription bundle or something else?

As per the documentation https://killbill.github.io/slate/invoice.html#invoice-groups invoice groups work at the account level and allow you to separate subscription bundles into separate invoice groups. 

Currently the default group is used for all subscriptions and appears to be using an implicit value which can not be set...I suspect that the subscription API will need to be updated to allow the invoice group to be modified from the DEFAULT group value to another invoice group value.  Current subscription API docs are here https://killbill.github.io/slate/subscription.html#create-a-subscription

Rgs
Shaun

--
You received this message because you are subscribed to the Google Groups "Kill Bill users mailing-list" group.
To unsubscribe from this group and stop receiving emails from it, send an email to killbilling-us...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/killbilling-users/cd56b5fb-34d5-4bb1-a165-7b73e4d1acafn%40googlegroups.com.


--
Shaun Forgie [Principal] - Method Maker Ltd
57a McIntyre Rd, Manukau 2022, Auckland, New Zealand
Mobile +64 21 666 910

vivek rao

unread,
Jul 30, 2024, 2:31:17 AM7/30/24
to Kill Bill users mailing-list
Hi Shaun

Our requirement is as follows.
  • We have multiple products : consider three products : P1, P2, P3
  • Account BCD is set to 1
  • In the Catalog, billingAlignment is set to BUNDLE
  • For each product there would be a bundle subscription recurring monthly
    • P1 - PLAN-1 --> Bundle Subscription BCD =1  (Billing on 1st of the month)
    • P2 - PLAN-21, PLAN-22 --> Bundle Subscription BCD = 2 (Billing on 2nd of the month)
    • P3 - PLAN-3 --> Bundle Subscription BCD = 2 (Billing on 2nd of the month)
  • Override Payment Methods
    • Account level CUSTOM FIELD will be added to define the PM_ID for each product. CUSTOM FIELD Key would have the Product Name. eg : <Product>_PM_ID
    • For product P1 : credit card (P1_PM_ID = 1)
    • For product P2 : credit card (P2_PM_ID = 2)
    • For product P3 : credit card (P3_PM_ID = 3)
Expectation:
  • On 1st of the Month, Invoice is to be generated for product P1 product for the PLAN-1 bundle subscription
    • This invoice can also follow the logic on Invoice splitting and since all items belong to one product P1 of one subscription bundle PLAN-1, it will result in only one group INV1
    • INV1 : Override payment method based on Account CUSTOM_FIELD P1_PM_ID=1
  • On 2nd of the Month, Invoice is to be generated for P2 and P3 products having the PLAN-21, PLAN-22 and PLAN-3 bundle subscription
    • this invoice will have invoice items of both products P2 and P3 of the three bundle subscriptions
    • We want to split this invoice based on subscription bundle IDs
      • INV1 : Having all the Invoice items of product P2 as per PLAN-21 and PLAN-22
      • INV2 : Having all the invoice items of product P3 PLAN-3
    • Once we have the invoice split into two groups, we want to override the payment method for each group
      • INV1 : Override payment method to based on Account CUSTOM_FIELD P2_PM_ID=2
      • INV2 : Override payment method to based on Account CUSTOM_FIELD P3_PM_ID=3
So to achieve the above result, we thought of using the invoice grouping function at the time of recurrence billing. 

KB Core would call the callback methods in below given order:
Usage Plugin : getUsageForAccount --> Invoice Plugin : getAdditionalInvoiceItems (invoice is generated after this step) --> Invoice Plugin : getInvoiceGrouping (generated invoice is split here)
Here we could iterate the Invoice Items and split it based on the products.

later in PaymentControl Plugin : getPaymentMethodId can be override to check and return the desired PM_ID to KB Core to initiate the charging

Hope above requirement is clear. Please suggest how this can be achieved.

Thanks
Vivek

Shaun Forgie

unread,
Jul 30, 2024, 5:37:02 AM7/30/24
to vivek rao, Kill Bill users mailing-list
HI Vivek,

To simplify things a bit I will try and summarise your requirements so that we can both understand what you are wanting to achieve.

Payment Requirements: 
PR1. Specify a payment type for a product for all account holders. For example
Product 1 is to be paid for with payment type 1 [Visa]
Product 2 is to be paid for with payment type 2 [Mastercard]
Product 3 is to be paid for with payment type 3 [Account Deposit / __external_payment__]

Note:
1. Specifying these generic payment type rules at a system level is not currently supported in either the catalog or in tenant properties. 
2. Only one payment type is to be specified for each product, not a set of payment types with a preferred order.

PR2. Record a payment type rule against an account/subscription object. The For example
Product 1 is to be paid for with payment type: Visa 

Note:
1. Data formatting / usage conventions. As you point out you could record this custom field | value against either the account or subscription object. A standard naming convention for this custom field [payment-type-rule] needs to be applied consistently to every object you record these values against. 
2. You would also need to ensure that these payment type options reflected the payment gateways the tenant had selected. Tenants can activate only a subset of the payment network plugins currently deployed within the system.
3. Different payment plugins can support the same payment type. So you will need to ensure that the rule identifies both the payment gateway / payment type that is to be used.
4. As outlined in the example above the custom field value would need to have at least three sections <product-name><payment-network>< payment-type>

General:
If you are only running Kill Bill with a single payment plugin and have a single biller tenancy these issues are minimised. But as your example provides three payment type methods I assume you have at least three payment plugins deployed.

The other comments you make around plans, alignment rules, and account BCDs are not relevant to the core requirements as I understand them. Also the use of invoicing groups is also not really needed if each subscription has its own billing cycle enabled. 

If you simply subscribed the customer to separate product plans with each plan having a monthly billing frequency this would result in the account holder receiving three separate invoices per month, one for each product subscription with each subscription dealing with a different product and payment method type. Subscriptions can be created with any start date/time and allow for backdating and forward dating scenarios that are independent of the account BCD. However it is worth noting that the first subscription you create for an account also sets the account BCD which can never be changed. Typically the start date for a subscription is the same as the date/time it was submitted.

Your suggested implementation would need to attach custom fields to either the invoice / subscription that specified the payment type rule for the product plan. Once the billing cycle is triggered you would have to supply modified invoice and payment plugins to deal with your custom payment method selection logic.

It will be easier to maintain if you ensure that you specify standalone plans having only one product. If you define the plans as base plans other add-ons may complicate your logic.

Hope that helps.

Rgs
Shaun


vivek rao

unread,
Jul 30, 2024, 1:43:17 PM7/30/24
to Kill Bill users mailing-list
Hi Shaun

Some clarifications on our requirement/use-case is given below.

We are having only one payment plugin in our deployment currently (it is the same stripe plugin from KB git repo)

We will be setting the payment method at the account level as CUSTOM FIELD(<product-name>_PM_ID = UUID of one Payment Method available at the account). and we would be setting the payment Method ID which is the UUID of the payment method in the KB when a we do account sync after configure the stripe API keys at the account level. So these UUIDs are unique in the system and it wont conflict with the same payment type of different payment plguin in case it gets added in the future in our deployment.

It is not guaranteed that each subscription will have its own billing cycle enabled. It can so happen that for some specific account there could be subscription bundles of all three products but configured BCD =1.  
In this case we would need invoices to be generated for each product separately. This is the use case where we want to leverage the invoice grouping function so that we can split the one invoice generated by KB(which would have line items of all three products) to 3 separate invoices which are product wise.

The main issue which we are facing now is that Invoice Plugin : getInvoiceGrouping is not getting called. Could you please provide some suggestions how to achieve this.
Overriding payment methods is the next step. Even if this doesn't work as expected atleast we need to have product wise invoices when BCD of all subscriptions are same day.

Thanks
Vivek

Shaun Forgie

unread,
Jul 30, 2024, 5:02:16 PM7/30/24
to vivek rao, Kill Bill users mailing-list
Vivek,

The point I am making is that you can meet your requirements without using Invoice Groups. You can use product specific plans with customers having separate subscriptions for each product with each subscription able to be set with the same or different monthly billing cycles. There was discussion about subscriptions being able to support separate payment methods but I am not sure whether this is currently supported out of the box. If not you could attach the payment methods to the subscription using custom fields as discussed. 

Invoice groups and associated payment method logic is a potentially nice feature but is not yet fully developed. You are better to use more standard configurations as I am suggesting with the use of product plans and subscriptions. 

Hope this helps.

Rgs
Shaun

vivek rao

unread,
Jul 30, 2024, 9:20:43 PM7/30/24
to Kill Bill users mailing-list
Hi Shaun

We are ok If our requirement is met without using the invoice grouping feature. But that is not happening now.

In our current deployment
    • Account BCD is set to 1
    • In the Catalog
        • billingAlignment is set to BUNDLE
        • has plans product specific plans
      • Each Account has one bundle subscription for each product. (In other words it mean each account has subscriptions done for one plan of each product)
      • Each Bundle subscription BCD is set to 2
      Now we are seeing that on 2nd of the month only one invoice is getting generated which has all three product line items. Our expectatio is to have thre seperate invoices on 2nd of every month.

      How to achieve this?

      Thanks
      Vivek

      Shaun Forgie

      unread,
      Jul 30, 2024, 10:13:57 PM7/30/24
      to vivek rao, Kill Bill users mailing-list
      Hi Vivek,

      So to summarise the configuration you need.

      1. Billing Plans: You have three standalone plans, one for each product, with a monthly billing cycle defined in your catalog.
      2. Customer subscriptions:  Three subscriptions, one for each product plan, are created separately for each customer
      3. Subscription BCD: All subscriptions will have a separate monthly invoice generation cycle set to the 1st of the month. This will override the default value of current date.
      4. Subscription activation: the billing activation alignment rule should be set to SUBSCRIPTION. For standalone plans having the BCD set to the 1st it ignores the BCD of both the parent bundle and account if they exist.
      5. Subscription Start Date: the subscription can start immediately [current date] or can be back dated / forward dated as required. If the plan has IN_ADVANCE billing enabled an invoice will be generated immediately for the period between the start date and the next BCD [1st of month]. If forward dated beyond the next BCD no invoice will be generated.

      Notes:
      1. Customer account BCD will be set upon creating the first subscription. In this example it will be set to the 1st of the month if the first subscription has a BCD value of 1st. 
      2. Payment methods: It is more intuitive to attach the custom field [payment-method-rule] to the subscription rather than the account.
      3. As I stated previously there is an outstanding enhancement request to support separate payment methods for a given subscription. See https://github.com/killbill/killbill/issues/277
      4. The invoice group you refer to is really better known as a subscription group. See https://github.com/killbill/killbill/issues/1658

      Hope this helps.

      Rgs
      Shaun

      vivek rao

      unread,
      Jul 31, 2024, 3:53:49 AM7/31/24
      to Kill Bill users mailing-list
      Hi Shaun

      1. Billing Plans: You have three standalone plans, one for each product, with a monthly billing cycle defined in your catalog.
      Yes we have one plan for each product in the catalog
      2. Customer subscriptions:  Three subscriptions, one for each product plan, are created separately for each customer
      Yes. We have only one account for testing and this account we have made 3 subscription for each of the product plans.
      3. Subscription BCD: All subscriptions will have a separate monthly invoice generation cycle set to the 1st of the month. This will override the default value of current date.
      All three subscriptions we have set BCD = 2
      4. Subscription activation: the billing activation alignment rule should be set to SUBSCRIPTION. For standalone plans having the BCD set to the 1st it ignores the BCD of both the parent bundle and account if they exist.
      Why it should be set to SUBSCRIPTION? We have set billing activation alignment rule to BUNDLE.  Because we have use-case of having BASE and ADD_ON products. So we would be needing invoice at Bundle level. 
      5. Subscription Start Date: the subscription can start immediately [current date] or can be back dated / forward dated as required. If the plan has IN_ADVANCE billing enabled an invoice will be generated immediately for the period between the start date and the next BCD [1st of month]. If forward dated beyond the next BCD no invoice will be generated.
      ok. this point is noted.

      With above configurations we are not getting one invoice for each bundle. As per above config we expect 3 invoices on 2nd of the month. But we are getting one Invoice with all 3 product's line items in it.
      This was the reason why started exploring the invoice split feature.

      If we can get 3 invoices on 2nd of the month, then we are good. Could you please suggest us how this can be achieved?

      Thanks
      Vivek

      Shaun Forgie

      unread,
      Jul 31, 2024, 5:25:45 AM7/31/24
      to vivek rao, Kill Bill users mailing-list
      Hi Vivek,

      In order to get three separate invoices,  one for each subscription, you will need define them as standalone plans and not as base plans with add-ons.

      As I mentioned before alignment should be SUBSCRIPTION but BUNDLE will also work if you use standalone plans.

      Rgs
      Shaun

      vivek rao

      unread,
      Jul 31, 2024, 6:01:45 AM7/31/24
      to Kill Bill users mailing-list
      Hi Shuan

      I assume you meant by STANDALONE Product and not plan.

      But we cannot use this in our case because we have a base product and 1 or more add on products that clients would be subscribed to. And those must be billed together.
      In future it is also possible to add few more add on products to the same subscription.

      In this case is it possible to generate invoice at bundle level? Base + all Add on product in this subscription bundle to be in one invoice.

      This is the reason why we have kept billing activation alignment rule to BUNDLE, hoping invoice will be generated at bundle level. If this is not the case then what is the purpose of having BUNDLE as the alignment? Do you mean that this alignment rule works only for STANDALONE Products?

      Anyways, know that you are clear with our requirement/use-case, could you please suggest how this can be achieved?

      Again I go back to the earlier point, if all bundle subscription invoice items come under one invoice, then does it make sense to use Invoice group feature to split this invoice at bundle level(this can be done spplitting the items based on bunde UUID).

      Thanks
      Vivek

      Shaun Forgie

      unread,
      Jul 31, 2024, 5:14:25 PM7/31/24
      to vivek rao, Kill Bill users mailing-list
      Hi Vivek,

      There are a few things going on in this discussion we need to be clear about....however the main issue is how best meet your primary requirement of "being able to pay for different products using different payment methods".

      Currently vanilla Kill Bill does not support this feature and will need to be modified to do so....which is where we are faced with a variety of different options which I will summarize shortly.

      You have designed a catalog that contains 3 separate products. One of the products is the main product which will form the base plan. The other two products will be add-ons [included | mandatory] or [extras | optional].

      The subscription plan structure seems natural and aligns with the user experience...but enforces some constraints on the invoicing and payment processing logic. 

      In Kill Bill the subscription drives the billing cycle and production of the invoices. In this case you are using a monthly billing frequency which also allows you to support consolidated invoicing at the account level through using the account BCD value, which is a monthly cycle and the most common use case.  However downstream payment processing is driven off the invoice...which means we get the following dependency chain: subscription -> invoice -> payment. This is core system logic and can not be easily changed with plugins which are intended to modify and enhance each stage but not the core processing sequence which we will have to follow.

      Invoicing alignment rules allow you to associate a subscription with either the parent account cycle, if the subscription plan has a monthly cycle, or its parent base plan, that supports all other cycle frequencies. You can also specify invoicing alignment with itself by using the SUBSCRIPTION alignment setting if you want to generate a separate invoice for the subscription.

      To meet your requirements you will have to generate a separate invoice for each subscription in the associated bundle which for a base plan with add-ons will mean 3 separate invoices with your invoicing alignment rules specified as SUBSCRIPTION. 

      Ok so to recap we have the system setup: catalog -> plan -> subscription -> invoice -> payment now configured correctly with separate monthly invoices being produced for all three subscriptions. The Kill Bill vanilla configuration is now sorted.

      The next steps require modifying the vanilla kill bill system with a few bespoke modifications. These are:
      1. Specifying which non default payment method to use for each subscription. Remember that only one account payment method is tagged as DEFAULT. For this we will create a custom field named [payment-method-logic] and assign it the value [payment method id] which references the account payment method to be used to pay the subscription. Note that you should create the custom field on the subscription object and not the account.
      2.  Payment Plugin: A new payment plugin will need to be developed that is aware of the custom field stored on against the subscription. If this custom value exists it will use that payment method if it does not exist then the DEFAULT account payment method will be used instead.

      Customer Account Management
      You are now creating additional responsibilities for ensuring each customer gets set up properly so that payment processing logic works correctly. You need to ensure you maintain all of the appropriate payment methods for each product plan the customer is subscribed to.

      This solution does not make use of subscription groups to generate separate invoices for each group. The feature is currently not fully implemented in either the subscription API [for specifying the group] or for managing subscription group definitions.

      Hope this helps.

      Rgs
      Shaun
      Reply all
      Reply to author
      Forward
      0 new messages