Jump to content

Automatically cancel small invoices and avoid invoice email


Recommended Posts

Hi all,

I'm trying to write a hook to automatically cancel tiny disk-space overusage invoices that WHMCS occasionally generates and avoid notifying the customer about them.  I saw something similar on these forums using PHP's MySQL API, I took inspiration and re-wrote using the WHMCS API's and have so far written the following:

function cancelSmall($vars) {
  $MIN_VALUE = 0.5;
  $NOTE = "Amounts under £0.50 are not payable. This invoice has been cancelled";

  logActivity("DEBUG: ".print_r($vars, true));

  $invoiceId = $vars['invoiceid'];

  logActivity("DEBUG: invoiceid=".$invoiceId);

  $invoiceDetail = Capsule::table('tblinvoices')->where('id', $invoiceId)->first();

  logActivity("DEBUG: ".print_r($invoiceDetail, true));
  logActivity("DEBUG: ".$invoiceDetail->total);

  if (($invoiceDetail->status == "Unpaid") && ($invoiceDetail->total <= $MIN_VALUE)) {
        logActivity("DEBUG: Invoice is smaller than minimum value and unpaid!");

        $command = 'UpdateInvoice';
        $postData = array(
                'invoiceid' => $invoiceId,
                'status' => 'Cancelled',
                'notes' => $NOTE,

        $results = localAPI($command, $postData);

        logActivity("DEBUG: ".print_r($results, true));
  } else {
        logActivity("DEBUG: Invoice is larger than minimum value or not unpaid!");

add_hook('InvoiceCreation', 1, 'cancelSmall');

When testing by generating invoices via the admin panel, the hook runs fine and small invoices are automatically marked as cancelled when they transition from the "Draft" to "Unpaid" status.  However, an invoice email is still sent out despite the invoice being marked as cancelled.  I am using the "Publish and send email" button, as I assumed this would use the same process as the automated invoice would use.

Am I missing something?


Edited by SeanC
Link to comment
Share on other sites

Hey Sean,

So WHMCS does have a InvoiceCreationPreEmail hook, however there is no way for it to abort the email from being sent.

Theoretically you could use the EmailPreSend hook to perform this action, as an email is always sent when an invoice is generated (unless you create an invoice and choose not to send the email). In fact, the below code will work for you.


use WHMCS\Database\Capsule;

function cancel_invoice_under_a_certain_amount($vars) {

    $amount         = 0.50;
    $notes          = 'Amounts under £0.50 are not payable. This invoice has been cancelled';
    $emailTemplates = ['Invoice Created', 'Credit Card Invoice Created'];

    $merge_fields = [];

    if (in_array($vars['messagename'], $emailTemplates)) {

        $invoice = Capsule::table('tblinvoices')->where('id', $vars['mergefields']['invoice_id'])->first();

        if ($invoice->status == "Unpaid" && $invoice->total <= $amount) {

            localAPI('UpdateInvoice', [
                'invoiceid' => $invoice->id,
                'status'    => 'Cancelled',
                'notes'     => $notes
            $merge_fields['abortsend'] = true;



    return $merge_fields;


add_hook('EmailPreSend', 1, 'cancel_invoice_under_a_certain_amount');

Though I don't really see the use case for this, instead of cancelling the invoice, would you not rather mark it as paid so all post payment actions would be executed?

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...

Important Information

By using this site, you agree to our Terms of Use & Guidelines and understand your posts will initially be pre-moderated