jBilling comes ‘out of the box’ with simple tax functionality. This means that without any customization, the system can handle the application of very basic taxes through the use of plugins.
One of the ways in which the system can handle simple taxes is to use the CountryTaxCompositionTask plugin, which will automatically assign country specific taxes for all products. The logic for this feature is based on the country code assigned to the customer. Alternatively, it is also possible to add a specific tax to a group of products. This can be done by using the SimpleTaxCompositionTask plugin. This plugin also provides the user with the ability to exempt products and customers from receiving tax. However, depending on how complex the taxes are, this plugin does not provide an easy way to apply taxes based on where the customer lives.
Applying taxes correctly is critical for all industries, but there are many complications when it comes to applying taxes to products and services for Telco. Compliancy is non negotiable, so when customers who reside in the United States are invoiced it can be incredibly time consuming to ensure that taxes are applied correctly. For example, federal, state, and local taxes are applied to all different combinations of services and products. One type of tax a particular customer needs, may not apply to the other. Additional types of taxes include: sales tax, telecommunications excise tax, utility users tax, business and occupations tax, gross receipt tax, and 911 fees.
Many billing systems attempt to handle taxes by using rate tables. The problem with this approach is that it does not take into account the plethora of scenarios a tax engine was built to handle with ease. As jBilling is a highly flexible and extensible system, with a complete API, our approach was to simply integrate with Avalara.
A plug-in was created in order to integrate jBilling with Avalara. This plug-in intercepts several events in the system’s billing lifecycle:
The plug-in intercepts modifications to the order and makes calls to calculate taxes. Calls made during order processing do not create Avalara transactions and are therefore not listed in the transaction log.
Invoice Composition and Creation
The plug-in intercepts the creation of an invoice from the purchase order in jBilling. This generates a call to Avalara to register a ‘Sales Invoice’, which gets saved to the transaction log, but in uncommitted state.
The plug-in intercepts invoice payment requests and commits the transaction in Avalara.
During the order processing and invoice composition phases in jBilling, the Avalara plug-in will calculate the appropriate taxes on the purchase order. The plug-in will apply the tax summary information returned by Avalara to add the tax lines to the customer’s invoice in jBilling. Each line will hold a different tax type. The plug-in will try to determine the item to create for each of these lines by matching a specified field against all defined tax items. If no item matches the tax code returned by Avalara, the plug-in will add the tax to the default tax line that must be specified as a parameter.
Invoice generation in jBilling invokes Avalara in two distinct steps:
Recalculation of the order before the actual invoice is created.
Since jBilling allows more than one purchase order per invoice, no document is registered in Avalara at this stage.
Actual invoice creation.
Invoices are registered in Avalara at this stage, and marked as "Posted".
Payment Handling and Commit
The plug-in intercepts successful payment events, and notifies Avalara by committing the invoice. Since jBilling allows several invoices to be paid using a single payment, the plug-in invokes Avalara once for each of the invoices included in the payment. Therefore, it is possible for a single payment to commit more than one invoice in Avalara.
The Avalara plug-in must be added to the "Order processing" and "Internal Events" plug-in chains in jBilling. The order of the plug-ins in these chains is important, and any line calculation plug-in must precede the Avalara plug-in so that the correct amounts are transferred.
Plug-in parameters also allow customization of this plug-in’s functionality. Each of the plug-in chains is separately configurable. You must configure both chains with the same parameters in order to avoid unexpected behavior in the plug-in.