Difference between revisions of "Billing Logic"

From WHMCS Documentation

(Renewal Invoices)
Line 44: Line 44:
 
* Ensure no invoice item exists for the service on the next invoice date
 
* Ensure no invoice item exists for the service on the next invoice date
 
* If the above points are evaluated to be true, then a new invoice is generated.
 
* If the above points are evaluated to be true, then a new invoice is generated.
* The InvoiceCreation Action Hook point is triggered
+
* The [https://developers.whmcs.com/hooks-reference/invoices-and-quotes/#invoicecreation InvoiceCreation] Action Hook point is triggered
* The InvoiceCreationPreEmail Action Hook point is triggered
+
* The [https://developers.whmcs.com/hooks-reference/invoices-and-quotes/#invoicecreationpreemail InvoiceCreationPreEmail] Action Hook point is triggered
 
* The Invoice Created email is sent to the client
 
* The Invoice Created email is sent to the client
* The InvoiceCreated Action Hook point is triggered
+
* The [https://developers.whmcs.com/hooks-reference/invoices-and-quotes/#invoicecreated InvoiceCreated] Action Hook point is triggered
 
* The Next Invoice Date of the service is incremented forward by one billing cycle.
 
* The Next Invoice Date of the service is incremented forward by one billing cycle.
  
Line 55: Line 55:
 
Automation upon payment is triggered by a transaction applied to an invoice which fully pays the balance, reducing it to 0.00 and marking an invoice paid. This means that editing an invoice and changing the status to Paid will ''not'' trigger automation. Upon adding payment to an invoice which is associated with a product/service or domain, the following actions occur:
 
Automation upon payment is triggered by a transaction applied to an invoice which fully pays the balance, reducing it to 0.00 and marking an invoice paid. This means that editing an invoice and changing the status to Paid will ''not'' trigger automation. Upon adding payment to an invoice which is associated with a product/service or domain, the following actions occur:
 
* A transaction is entered into the database
 
* A transaction is entered into the database
* The AddTransaction Action Hook point is triggered
+
* The [https://developers.whmcs.com/hooks-reference/invoices-and-quotes/#addtransaction AddTransaction] Action Hook point is triggered
 
* The transaction amount is subtracted from the invoice balance
 
* The transaction amount is subtracted from the invoice balance
 
* If the invoice balance is now 0, the invoice is marked as paid.
 
* If the invoice balance is now 0, the invoice is marked as paid.
 
* The invoice status is changed to Paid
 
* The invoice status is changed to Paid
* The InvoicePaidPreEmail Action Hook point is triggered
+
* The [https://developers.whmcs.com/hooks-reference/invoices-and-quotes/#invoicepaidpreemail InvoicePaidPreEmail] Action Hook point is triggered
 
* A payment confirmation email is sent to the client
 
* A payment confirmation email is sent to the client
 
* The Next Due Date of the associated service/domain is incremented forward by one billing cycle.
 
* The Next Due Date of the associated service/domain is incremented forward by one billing cycle.
* The InvoicePaid Action Hook point is triggered
+
* The [https://developers.whmcs.com/hooks-reference/invoices-and-quotes/#invoicepaid InvoicePaid] Action Hook point is triggered
  
 
===Overpayments===
 
===Overpayments===
Line 83: Line 83:
 
** A credit is added to the client's account with the description ''Credit from Refund of Invoice ID #''
 
** A credit is added to the client's account with the description ''Credit from Refund of Invoice ID #''
 
* A negative transaction is recorded against the invoice
 
* A negative transaction is recorded against the invoice
* The AddTransaction Action Hook point is triggered
+
* The [https://developers.whmcs.com/hooks-reference/invoices-and-quotes/#addtransaction AddTransaction Action Hook] point is triggered
 
* The invoice's balance is increased by the refunded amount
 
* The invoice's balance is increased by the refunded amount
 
* If the full balance is refunded, the invoice's status changes to Refunded
 
* If the full balance is refunded, the invoice's status changes to Refunded
* The InvoiceRefunded Action Hook point is triggered
+
* The [https://developers.whmcs.com/hooks-reference/invoices-and-quotes/#invoicerefunded InvoiceRefunded] Action Hook point is triggered
 
* The Invoice Refund Confirmation email is sent to the client
 
* The Invoice Refund Confirmation email is sent to the client
  
Line 148: Line 148:
 
* Determine if the date is equal to or less than the number of days in the future specified by the Suspension Days setting
 
* Determine if the date is equal to or less than the number of days in the future specified by the Suspension Days setting
 
* Determine if Automated Suspension is enabled in [[Automation Settings]]
 
* Determine if Automated Suspension is enabled in [[Automation Settings]]
* If this is evaluated to be true, the PreModuleSuspend Action Hook point is triggered
+
* If this is evaluated to be true, the [https://developers.whmcs.com/hooks-reference/module/#premodulesuspend PreModuleSuspend] Action Hook point is triggered
 
* The services is suspended  
 
* The services is suspended  
* If the module returns a success response, the AfterModuleSuspend Action Hook point is triggered
+
* If the module returns a success response, the [https://developers.whmcs.com/hooks-reference/module/#aftermodulesuspend AfterModuleSuspend] Action Hook point is triggered
* If the module returns a failed response, the AfterModuleSuspendFailed Action Hook point is triggered.
+
* If the module returns a failed response, the [https://developers.whmcs.com/hooks-reference/module/#aftermodulesuspendfailed AfterModuleSuspendFailed] Action Hook point is triggered.
  
 
==Unsuspension==
 
==Unsuspension==
Line 159: Line 159:
 
* The Enable Unsuspension option is enabled in [[Automation Settings]]
 
* The Enable Unsuspension option is enabled in [[Automation Settings]]
 
* The service has a suspension reason of "Overdue on Payment"
 
* The service has a suspension reason of "Overdue on Payment"
* If the above points are evaluated to be true, the PreModuleUnsuspend Action Hook point is triggered
+
* If the above points are evaluated to be true, the [https://developers.whmcs.com/hooks-reference/module/#premoduleunsuspend PreModuleUnsuspend] Action Hook point is triggered
 
* The service is unsuspended
 
* The service is unsuspended
* If the module returns a success response, the AfterModuleUnsuspend Action Hook point is triggered
+
* If the module returns a success response, the [https://developers.whmcs.com/hooks-reference/module/#aftermoduleunsuspend  AfterModuleUnsuspend] Action Hook point is triggered
* If the module returns a failed response, the AfterModuleUnsuspendFailed Action Hook point is triggered.
+
* If the module returns a failed response, the [https://developers.whmcs.com/hooks-reference/module/#aftermoduleunsuspendfailed AfterModuleUnsuspendFailed] Action Hook point is triggered.
  
 
===Continuous Invoice Generation===
 
===Continuous Invoice Generation===
Line 172: Line 172:
 
* Determine if the date is equal to or less than the number of days in the future specified by the Termination Days setting
 
* Determine if the date is equal to or less than the number of days in the future specified by the Termination Days setting
 
* Determine if Automated Termination is enabled in [[Automation Settings]]
 
* Determine if Automated Termination is enabled in [[Automation Settings]]
* If this is evaluated to be true, the PreModuleTerminate Action Hook point is triggered
+
* If this is evaluated to be true, the [https://developers.whmcs.com/hooks-reference/module/#premoduleterminate PreModuleTerminate] Action Hook point is triggered
 
* The services is terminated
 
* The services is terminated
* If the module returns a success response, the AfterModuleTerminate Action Hook point is triggered
+
* If the module returns a success response, the [https://developers.whmcs.com/hooks-reference/module/#aftermoduleterminate AfterModuleTerminate] Action Hook point is triggered
* If the module returns a failed response, the AfterModuleTerminateFailed Action Hook point is triggered.
+
* If the module returns a failed response, the [https://developers.whmcs.com/hooks-reference/module/#aftermoduleterminatefailed AfterModuleTerminateFailed] Action Hook point is triggered.

Revision as of 23:19, 5 December 2017

This document explains the billing and invoicing logic used in the WHMCS software. Having an understanding of these core elements of the software will enable years of smooth and trouble-free operation.

Ordering

When a new visitor places an order a number of new records are created which contain the various pieces of information captured on the order form:

  • A client record is created to store the customer's contact details and payment preferences.
  • The service and domain record(s) are then created which contain the details of the service the client selected on the order form.
  • Next an invoice record is created which records the amount to be paid, when it is due to be paid and how payment should be made.
  • Finally, an order record is created which ties all of the above together and records the fraud report details (if enabled). The order is a static record which reflects the prices and items at the time of ordering, subsequent changes will not be reflected on the order.

Invoicing

Initial Invoice

When an invoice is created by an initial order, the default behaviour is that the invoice is due on the day of ordering. The exception being if the Order Grace Days setting is used, in which case the invoice due date will be set x days to the future.

Upon payment of the initial invoice, the system checks the associated products to determine if any automation should be taken based upon the Module Settings. This could be one of the following actions:

  • Automatically setup the product as soon as an order is placed
  • Automatically setup the product as soon as the first payment is received
  • Automatically setup the product when you manually accept a pending order
  • Do not automatically setup this product

The service's Next Due Date value is then incremented forward one billing cycle (ie. 1 month, 3 months, 6 months, 1 year, 2 years or 3 years).

Renewal Invoices

The date at which the next payment is due is controlled by the Next Due Date of the service. When the cron executes the daily automation tasks the following actions are performed:

  • The Next Due Date of all Active, Pending and Suspended services are analysed
  • Determine if the date is equal to or less than the number of days in the future specified by the Invoice Generation setting
  • Ensure no invoice item exists for the service on the next due date
  • If the above points are evaluated to be true, then a new invoice is generated.
  • The InvoiceCreation Action Hook point is triggered
  • The InvoiceCreationPreEmail Action Hook point is triggered
  • The Invoice Created email is sent to the client
  • The InvoiceCreated Action Hook point is triggered
  • The Next Invoice Date of the service is incremented forward by one billing cycle.

In this way, WHMCS will never generate two invoices for a given product, service or domain with the same due date - even if the original invoice has been cancelled or deleted.

As the Next Due Date is incremented forward based upon the previous value, this means paying an invoice after the due date will not change the client's renewal date to reflect the date of payment. A service is always invoices for a contiguous period without gaps, this avoids a situation whereby a customer might hope to avoid paying for a service by intentionally paying late.

Continuous Invoice Generation

When the Continuous Invoice Generation option is enabled in the general settings, the invoice generation logic is altered so that renewal invoices are created even if the previous one is unpaid.

This is facilitated by a checking a hidden field in the service record called Next Invoice Date. The Next Invoice Date field maintains a separate record of the due date for next invoice to be generated. The Next Due Date value determines the next invoice to be paid.

In this mode, when the cron executes the daily automation tasks the following actions are performed:

  • The Next Invoice Date of all Active, Pending and Suspended services are analysed
  • Determine if the date is equal to or less than the number of days in the future specified by the Invoice Generation setting
  • Ensure no invoice item exists for the service on the next invoice date
  • If the above points are evaluated to be true, then a new invoice is generated.
  • The InvoiceCreation Action Hook point is triggered
  • The InvoiceCreationPreEmail Action Hook point is triggered
  • The Invoice Created email is sent to the client
  • The InvoiceCreated Action Hook point is triggered
  • The Next Invoice Date of the service is incremented forward by one billing cycle.

In this way, WHMCS maintains a separate record of which invoice should be generated and which payment is due.

Payments

Automation upon payment is triggered by a transaction applied to an invoice which fully pays the balance, reducing it to 0.00 and marking an invoice paid. This means that editing an invoice and changing the status to Paid will not trigger automation. Upon adding payment to an invoice which is associated with a product/service or domain, the following actions occur:

  • A transaction is entered into the database
  • The AddTransaction Action Hook point is triggered
  • The transaction amount is subtracted from the invoice balance
  • If the invoice balance is now 0, the invoice is marked as paid.
  • The invoice status is changed to Paid
  • The InvoicePaidPreEmail Action Hook point is triggered
  • A payment confirmation email is sent to the client
  • The Next Due Date of the associated service/domain is incremented forward by one billing cycle.
  • The InvoicePaid Action Hook point is triggered

Overpayments

If a transaction is applied with an amount greater than the balance of the invoice, the following actions are taken:

  • The entire transaction is recorded against the invoice, thus making the balance negative
  • The invoice is marked paid
  • The difference between the balance and the transaction amount is credited to the client's account
  • The credit description will take the format Invoice # Overpayment

Sometimes, fixed payments services (such as PayPal Subscriptions and 2Checkout Recurring Payments) can send a payment when no payment is due. In these situations, the following actions occur:

  • The entire transaction is recorded against the invoice which originally created the billing agreement, thus making the balance negative
  • The full transaction amount is credited to the client's account
  • The credit description will take the format Invoice # Overpayment

Refunds

Transactions applied to invoices can be refunded via the Refunds tab. When a refund is initiated the following actions occur:

  • The selected refund action is performed, either of the following:
    • A refund command is sent to the payment gateway (if supported)
    • A credit is added to the client's account with the description Credit from Refund of Invoice ID #
  • A negative transaction is recorded against the invoice
  • The AddTransaction Action Hook point is triggered
  • The invoice's balance is increased by the refunded amount
  • If the full balance is refunded, the invoice's status changes to Refunded
  • The InvoiceRefunded Action Hook point is triggered
  • The Invoice Refund Confirmation email is sent to the client

If the transaction being refunded resulted in a credit to the client's account, you will be required to choose how to handle the credit:

  • Remove the refunded amount from the credit balance.
  • Leave the credit untouched.

Payment Reversals

When issuing a refund there is also the option to reverse the payment. This is useful when you want to reverse the automated actions triggered by the payment, typically in the event of a payment dispute or chargeback.

The actions which are taken when reversing a payment are context sensitive and depend upon your payment reversal settings. For an in-depth discussion of this feature, refer to the Payment Reversals page.

Billing Cycles

A billing cycle is considered a calendar period, so "1 month" is not a consistent period of days. When you agree to bill by the month, you are charging the same amount of money for different amounts of service. WHMCS uses the php date function's computation to figure out the next due date. We tell it to add a month and return the date, which we set as the Next Due Date.

February

Due to the shorter length of February this can cause some unique behaviour which does not happen for the other 11 months of a year:

Order Date Renewal Date Number of Days
January 29 March 1 31 days
January 30 March 2 31 days
January 31 March 3 31 days
February 1 March 1 28 days
February 2 March 2 28 days
February 3 March 3 28 days


Suspension

The date at which services are suspended is controlled by the Next Due Date of the service. When the cron executes the daily automation tasks the following actions are performed:

  • The Next Due Date of all Active and Pending services are analysed
  • Determine if the date is equal to or less than the number of days in the future specified by the Suspension Days setting
  • Determine if Automated Suspension is enabled in Automation Settings
  • If this is evaluated to be true, the PreModuleSuspend Action Hook point is triggered
  • The services is suspended
  • If the module returns a success response, the AfterModuleSuspend Action Hook point is triggered
  • If the module returns a failed response, the AfterModuleSuspendFailed Action Hook point is triggered.

Unsuspension

When payment is made against an invoice which is associated with a service in Suspended status the service can be automatically unsuspended. In addition to the actions listed in Payments, the following additional actions are performed:

  • The invoice is associated with a service in Suspended status
  • The Enable Unsuspension option is enabled in Automation Settings
  • The service has a suspension reason of "Overdue on Payment"
  • If the above points are evaluated to be true, the PreModuleUnsuspend Action Hook point is triggered
  • The service is unsuspended
  • If the module returns a success response, the AfterModuleUnsuspend Action Hook point is triggered
  • If the module returns a failed response, the AfterModuleUnsuspendFailed Action Hook point is triggered.

Continuous Invoice Generation

When used in conjunction with continuous invoice generation, paying a recent invoice whilst leaving an older invoice unpaid will keep the service suspended. The exception being if the payment were to increment the Next Due Date forward to a date at which the service was no longer within the Suspension date range - in that case the service would be unsuspended.

Termination

The date at which services are terminated is controlled by the Next Due Date of the service. When the cron executes the daily automation tasks the following actions are performed:

  • The Next Due Date of all Active, Suspended and Pending services are analysed
  • Determine if the date is equal to or less than the number of days in the future specified by the Termination Days setting
  • Determine if Automated Termination is enabled in Automation Settings
  • If this is evaluated to be true, the PreModuleTerminate Action Hook point is triggered
  • The services is terminated
  • If the module returns a success response, the AfterModuleTerminate Action Hook point is triggered
  • If the module returns a failed response, the AfterModuleTerminateFailed Action Hook point is triggered.