Billing integrations

ZATCA Tools for WHMCS

An addon module for WHMCS. Once installed, every paid invoice becomes a Saudi Phase-2 e-invoice, signed and reported to the Zakat, Tax and Customs Authority, and every refund becomes a credit note. Hosting, domains, and anything else you bill through WHMCS.

Version 1.1.0. Open source: read the code before you install it.

How it works

When an invoice in WHMCS is marked paid, the addon sends it to ZATCA Tools. Its lines (hosting, domains, addons, promotional discounts) become a Phase-2 compliant tax invoice: simplified for individuals, standard (B2B) for Saudi companies with a VAT number. We sign it with your establishment's certificate and report it to the Authority within seconds. The e-invoice number, QR code and PDF link appear on the invoice page in the WHMCS admin area, on your client's invoice page, and in the Invoices page of your ZATCA Tools account.

Invoice paid in WHMCS → Signed e-invoice → Reported to ZATCA

Before you start

  • A ZATCA Tools account connected to Fatoora. Complete the connection in Settings first.
  • WHMCS 8.0 or newer, PHP 7.4 or newer with cURL.
  • Client currency Saudi Riyal (SAR). Invoices in other currencies are refused with the reason shown.
  • A 15% tax rule for Saudi Arabia in WHMCS (Setup, Payments, Tax Rules). Without it your Saudi clients are billed at zero VAT and no e-invoice is issued for them.
Tax in WHMCS. The addon reads the tax rate fixed on the invoice and handles both tax types: Exclusive (VAT added on top of the price) and Inclusive (prices already contain VAT). An invoice for a Saudi client with taxable items and no VAT means a missing tax rule, so the addon stops and explains why on its page instead of reporting a wrong figure to the Authority.

Step 1. Install the addon

  1. Download the .zip and extract it.
  2. Upload the modules/addons/zatcatools folder into modules/addons/ of your WHMCS installation.
  3. In the admin area open Setup, Addon Modules and click Activate next to ZATCA Tools.
  4. Activation creates a table that maps your invoices to their e-invoices, and two client fields for the VAT number and the national short address.

Step 2. Paste your API key

  1. In ZATCA Tools open Settings, API and copy the key (it starts with ztk_live_).
  2. In WHMCS: Setup, Addon Modules, ZATCA Tools, Configure. Paste the key, choose when to issue (on payment is the default and the recommendation), and grant access to your admin roles.
  3. Open Addons, ZATCA Tools: a connection card shows your establishment and remaining plan quota, plus a setup checklist (fields, tax rule, currency).

Step 3. Business clients

Individuals get a simplified tax invoice with no setup. A Saudi company that needs a tax invoice in its name needs two fields on its client profile. The addon creates them on activation and shows them on the order form:

FieldWhat it does
VAT Number zatca_vat15 digits, starting and ending with 3. When present, the client receives a standard (B2B) tax invoice. The built-in WHMCS Tax ID field is read as a fallback.
National Short Address zatca_short_addressEight characters such as RRRD2929. From it we resolve the street, building number, district, city and postal code the Authority requires on a tax invoice.

Step 4. Try one invoice

  1. Create a small invoice for a test client and mark it paid.
  2. Open the invoice in the admin area: a ZATCA e-invoice box shows its status, number and PDF link.
  3. Open the same invoice from the client account: the QR code and the e-invoice download link are there.
  4. If something is off (missing key, incomplete address, non-SAR currency) the exact reason is listed under Addons, ZATCA Tools with a Retry button.

QR code on the PDF that WHMCS generates

The signed e-invoice has its own PDF on ZATCA Tools. To print the QR code and the e-invoice number on the WHMCS invoice PDF as well, paste this block into your template's templates/<your-template>/invoicepdf.tpl before the invoice items table:

$zatcaDocument = \WHMCS\Database\Capsule::table('mod_zatcatools_documents')
    ->where('invoice_id', (int) $invoiceid)->where('kind', 'invoice')
    ->whereIn('status', ['issued', 'warnings'])->orderByDesc('id')->first();

if ($zatcaDocument && ! empty($zatcaDocument->qr_svg)) {
    $pdf->ImageSVG('@'.$zatcaDocument->qr_svg, 160, 12, 32, 32);
    $pdf->SetXY(156, 45);
    $pdf->SetFont($pdfFont ?? 'freesans', '', 7);
    $pdf->Cell(40, 4, 'ZATCA '.$zatcaDocument->number, 0, 1, 'C');
}

The same file ships in the package as snippets/invoicepdf-qr.php. Custom themes also receive {$zatcatools.number}, {$zatcatools.view_url} and {$zatcatools.qr_svg} as template variables on the invoice page.

Details that matter

  • Never a duplicate. Each WHMCS invoice maps to exactly one document, however often the hook fires, the cron overlaps, or someone clicks "Issue now" after the system already did. An accepted e-invoice cannot be deleted, which makes this the most important property of the addon.
  • Refunds. A partial refund in WHMCS issues a credit note for the refunded amount with VAT backed out. A full refund or a cancellation issues a credit note for the open balance only, so a partial refund is never credited twice.
  • Promotional discounts. Negative Promotional Code lines in WHMCS become a document-level discount, or come off the lines they reduced on an invoice that mixes taxed and untaxed items, so the e-invoice total matches the WHMCS total. Where it cannot (a second-level tax rule, a currency rate) the difference is written out on the invoice for you.
  • Clients outside Saudi Arabia. You choose in the settings how their lines are reported: zero-rated export of services, outside the scope of VAT, or not issued at all.
  • Advance payments. With Advance payments set to prepayment invoices, an Add Funds payment is issued as a prepayment invoice (ZATCA type 386, VAT due when the money is received). When that credit later pays an invoice, the e-invoice states the whole supply and its VAT, takes the advance and its VAT off, and asks for the rest: a 1,000 deposit on a 2,000 job is one 1,000 advance invoice and one 2,000 invoice with 1,000 due — the VAT counted once. Left off (the default), Add Funds is not invoiced and the VAT is reported on the invoice the credit pays.
  • Invoices that are not sales. Mass Payment invoices are skipped: the invoices they pay carry the e-invoices. A mass payment refunded in full credits each invoice it paid.
  • Untaxed items. An item WHMCS charged no VAT on for a Saudi client is stopped with its name by default — almost always a product not marked taxable. Choose in the settings if such items really are outside the scope, exempt or zero-rated.
  • Changes after issue. An invoice edited after its e-invoice was accepted is flagged on the invoice page with the difference; an invoice cancelled (credited) and then paid gets a debit note that reverses the credit.
  • Transient failures. A network outage is retried by the WHMCS cron with increasing backoff for about eight hours, and a refund made before its e-invoice existed waits and follows it. Failures that have a reason (a missing tax rule, a buyer the Authority cannot identify) wait for you on the addon page, where Retry all failed sends them again once fixed.
  • More than one WHMCS installation on one account? Each installation gets its own identifier derived from its system URL, so invoice ids do not collide between them. A copy of your WHMCS at another address (a staging site restored from production) issues nothing until you confirm on the addon page that it is your live system.
  • Which version do I have? The addon page shows it at the top (Addons, ZATCA Tools), as does System Settings, Addon Modules. This page always offers the latest.
  • Logs. Every API call is in Utilities, Logs, Module Log with the key masked; outcomes are in the Activity Log.
  • Every e-invoice counts against your plan. Track what is left on the connection card of the addon page or in your ZATCA Tools dashboard.

Changelog

1.1.0
  • Advance payments: Add Funds as a prepayment invoice (386), deducted from the invoice its credit pays.
  • A credit note that failed is retried with its own request (1.0.x lost it and could not resend).
  • A retried second attempt keeps its own id instead of returning to the rejected first.
  • A refund made before the e-invoice was issued waits for it instead of being dropped.
  • Invoices waiting on ZATCA's verdict are checked again by the cron instead of showing as failed.
  • The client-area QR panel is shown only to the client who owns the invoice.
  • Untaxed items are stopped by default; second-level tax rules are refused; optional conversion of other currencies to SAR.
  • Partial refunds carry their VAT treatment; a refund of the whole e-invoice is credited in full.
  • Debit note when a cancelled invoice is paid; flag when an invoice changes after issue; mass-payment refunds.
  • A copy of WHMCS at another System URL is paused until confirmed; Retry all failed; the version on the addon page.
1.0.1
  • Promotions on invoices mixing taxed and untaxed items come off the lines they reduced.

To update: upload the new files over the old ones; WHMCS runs the upgrade (new columns, nothing removed) the next time the addon page opens.

FAQ

When is the e-invoice issued: when the WHMCS invoice is created, or when it is paid?

When it is paid, by default. That is the right moment for a hosting company: the tax point is the payment, and with proforma invoicing the invoice number is final by then. You can switch to "when created" in the addon settings.

My client is a Saudi company and wants a tax invoice in its name. How?

Add its VAT number and national short address in the two client fields the addon creates on activation. From then on it receives a standard (B2B) tax invoice instead of a simplified one, and the full address is resolved from the short address.

What happens on a refund or a cancellation?

Partial refunds, full refunds and cancellations after issue become a credit note tied to the original e-invoice. The open balance is computed on our side, so a partial refund is never credited twice.

Does the addon print the QR on the PDF that WHMCS generates?

Yes, with a snippet you paste into invoicepdf.tpl (the code is on this page). Without it, the QR and the e-invoice link still show on the client invoice page and in the admin area.

Is the addon free?

Yes. The addon is open source and free; each e-invoice counts against your ZATCA Tools plan like any other channel.

Installing for the first time? Contact us and we will run the first invoice with you on a WHMCS staging copy before production.