├── LICENSE ├── README.md └── cancelinvoice_hook.php /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # whmcs-cancelinvoice-hook 2 | Hook for WHMCS which will cancel overdue invoices automatically after x days 3 | 4 | This has been requested by the community 7 years ago at requests.whmcs.com and is still being investigated :-) 5 | I bet: this functionality will never come, because of the many different jurisdiction and legal requirements throughout the world. 6 | 7 | Original request: https://requests.whmcs.com/topic/cancel-x-days-overdue-invoices 8 | 9 | Just copy the hook file into /includes/hooks and adjust the $overduedays var in the hook. 10 | 11 | WHMCS 7.4 and above. 12 | 13 | n-joy 14 | 15 | 16 | # Changes: 17 | 18 | 20200514 feature: added second hook for auto-cancelling long pending orders too. 19 | 20 | 20200226 bugfix: removed "]" sign in line 22 (logactivity) and changed "AfterCronJob" hook to "DailyCronJob". 21 | 22 | Due to a confirmed Bug in WHMCS Core, the InvoiceCancelled Hook will not fire when changing invoice status by API call. 23 | (internal case #CORE-14322). Until this has been fixed by WHMCS, you need to make sure no other module etc. need to be notified for status changes. 24 | 25 | 26 | -------------------------------------------------------------------------------- /cancelinvoice_hook.php: -------------------------------------------------------------------------------- 1 | where("status","Unpaid")->where("duedate","<",date("Y-m-d",strtotime("-$overduedays days")))->get(); 15 | 16 | foreach($invoices as $invoice) 17 | { 18 | //use UpdateInvoice API Call for changing the status, otherwise the InvoiceCancelled hook will not trigger 19 | //and may affect other modules/apps which rely on this hook. 20 | $results = localAPI("UpdateInvoice",array("invoiceid"=>$invoice->id,"status"=>"Cancelled")); 21 | if ($results["result"]=="success") 22 | logactivity("[INVOICECANCELHOOK] has cancelled Invoice ID: $invoice->id automatically."); 23 | } 24 | 25 | }); //hook 26 | 27 | 28 | //process long pending orders the same way as overdue invoices 29 | 30 | add_hook('DailyCronJob',2,function($vars) 31 | { 32 | 33 | // As requested by someone, we can use this hook also for cancelling long pending orders (dead orders) 34 | // 35 | // Change $overduedays to whatever you need. Default is cancel all orders after pending for 14 days. 36 | // 37 | $overduedays=14; 38 | $orders=Capsule::table("tblorders")->where("status","Pending")->where("date","<",date("Y-m-d",strtotime("-$overduedays days")))->get(); 39 | 40 | foreach($orders as $order) 41 | { 42 | //use CancelOrder API Call for changing the status 43 | $results = localAPI("CancelOrder",array("id"=>$order->id,"status"=>"Cancelled")); 44 | if ($results["result"]=="success") 45 | logactivity("[ORDERCANCELHOOK] has cancelled Order ID: $order->id automatically."); 46 | } 47 | 48 | }); //hook 49 | 50 | 51 | 52 | 53 | --------------------------------------------------------------------------------