Invoice Pilot
Invoice Pilot extends WooCommerce with country-aware invoicing for the 27 EU member states. It captures the right billing fields at checkout (Italian SDI / PEC codes, French SIRET, German Leitweg-ID, Polish NIP, Romanian CUI, and so on), then issues immutable PDF and XML invoices, credit notes, proformas and quotes from the order. The PDF is rendered with mPDF; the XML envelope is picked automatically from the buyer’s country and covers eleven national profiles including FatturaPA (IT), XRechnung (DE), KSeF FA(2) (PL), Factur-X (FR), CIUS_RO (RO), Facturae (ES) and UBL 2.1 / PEPPOL BIS 3.0 as the generic fallback.
Beyond the document engine, Invoice Pilot ships first-class integrations with SmartBill (Romania) and Fatture in Cloud (Italy), a VAT validator that consults the European VIES service with a per-country format fallback, a dashboard with KPI cards and trend charts, and an optional multi-provider AI layer (Anthropic Claude, OpenAI, Google Gemini) for checkout smart-fill, compliance pre-flight, line translation and natural-language invoice search. The plugin also supports WordPress Multisite with per-site tables and a network-wide overview page.
Highlights
- WooCommerce-driven document lifecycle for invoices, credit notes, proformas and quotes, with reserved numbering series and a clean issue / regenerate / reissue / void / credit-note flow.
- EU-27 country-specific billing fields registered against both the legacy shortcode checkout and the WooCommerce 8.6+ block checkout (via the Additional Checkout Fields API).
- PDF rendering through mPDF using one of three bundled templates (Minimal, Classic, Modern), with picker for accent colour, text colour, font family and seller logo.
- Eleven XML writers, dispatched automatically from the buyer country: FatturaPA (IT), Factur-X / CII (FR), XRechnung 3.0 (DE), KSeF FA(2) (PL), CIUS_RO 1.0.0 (RO), Facturae 3.2.2 (ES), SAF-T PT (PT), OIOUBL (DK), Finvoice 3.0 (FI), ebInterface 6.1 (AT), myDATA InvoicesDoc (GR / EL), with UBL 2.1 / PEPPOL BIS 3.0 as the universal fallback.
- VAT validation chain combining the European VIES SOAP service with offline per-country regex validation, a DB-backed cache and an hourly cron that revalidates stale entries.
- SmartBill and Fatture in Cloud integrations with encrypted credentials, push / status / void operations and a retry queue.
- Optional AI layer with three providers (Anthropic, OpenAI, Gemini) covering smart-fill, compliance check, line translation and natural-language search; the plugin works fully without an API key.
- Dashboard with period selector, five KPI cards and two trend charts; a separate Integration Log records every push and failure.
- WordPress Multisite support — each sub-site has its own tables, settings and numbering counters, with a network admin page that aggregates statistics.
Requirements
| Component | Minimum |
|---|---|
| WordPress | 5.8 |
| PHP | 8.0 |
| WooCommerce | 7.0 |
| Database | MySQL 5.7 or MariaDB 10.2 (the dashboard SQL uses JSON_EXTRACT / JSON_UNQUOTE against the immutable snapshot column) |
The block-checkout integration is registered against the WooCommerce
Additional Checkout Fields API (introduced in WooCommerce 8.6). On
older WooCommerce versions the legacy woocommerce_billing_fields
filter still adds VAT, tax-code and country-specific fields to the
shortcode checkout, so the plugin degrades gracefully.
Installation
- Download the latest Invoice Pilot ZIP from the GitHub Releases page.
- In WordPress, open Plugins → Add New → Upload Plugin.
- Choose the ZIP and click Install Now.
- Click Activate Plugin.
- Open Invoice Pilot → Settings to configure the seller, numbering series and optional integrations.
Activation creates the plugin’s database tables, installs the default
settings and seeds five numbering series (one per document type):
INV (invoice, default), REC (receipt), CN (credit note), PRO
(proforma) and Q (quote), all using the YYYY-NNNN pattern with a
yearly reset. Four cron jobs are also scheduled: daily log cleanup,
fifteen-minute retry of failed integration pushes, hourly VIES
revalidation and daily Fatture in Cloud token refresh.
On WordPress Multisite, the same per-site bootstrap runs automatically
when a new sub-site is created (wp_initialize_site).
Configuration
All Invoice Pilot screens live under the top-level Invoice Pilot menu in the WordPress admin sidebar:
- Dashboard — KPI cards and trend charts.
- Invoices — list of issued documents with status filters and quick actions.
- Settings — eight-tab configuration page (documented below).
- Log — integration log entries with retention and a manual cleanup action.
The Settings page is split into the following tabs, in the order they appear in the UI:
- General
- Series
- Document types
- Templates
- VAT validation
- Integrations
- AI
- Advanced
General
The General tab carries seller identity (printed on every issued document) and a small number of WooCommerce-level defaults.
| Field | Default | Notes |
|---|---|---|
| Seller name | empty | Free text. |
| VAT | empty | Seller VAT identifier. |
| Tax code | empty | Italian codice fiscale or equivalent. |
| Address | empty | Street. |
| ZIP / CAP | empty | Postal code. |
| City | empty | |
| Province (2 letters, IT only) | empty | Force-uppercased on save. |
| Country (ISO, 2 letters) | IT | ISO-3166-1 alpha-2; force-uppercased. |
| empty | Validated as an email address. | |
| Logo | empty | Picked from the WordPress Media Library. PNG or SVG with a transparent background works best; recommended height 64–128px. The logo is printed top-right on the invoice. |
| IBAN | empty | Used by writers that emit payment instructions. |
| Trigger status | processing | WooCommerce order status that triggers automatic invoice issuance. Allowed values: processing, completed, on-hold, pending. |
| Default series | INV | Slug of the numbering series used for new invoices. |
| All EU-27 fields at checkout | off | When off, only the Italian SDI / PEC fields are exposed in the block checkout. When on, every country-specific field in the registry is exposed (verbose, but useful on multi-country shops). The legacy shortcode checkout always shows the full registry. |
Series
The Series tab is a CRUD table over the numbering series stored in
the plugin’s own series table. Each row controls how documents of a
given type are numbered.
Columns: Slug, Pattern, Counter, Reset, Default, Enabled, Actions (Edit / Delete).
The Add / Edit form exposes:
| Field | Allowed values | Default |
|---|---|---|
| Slug | Lowercase identifier. Must be unique. | empty |
| Document type | invoice, receipt, credit_note, proforma, quote. | invoice |
| Pattern | Free text; placeholders {YYYY} (year) and {NNNN} (counter) are expanded at issue time. | INV-{YYYY}-{NNNN} |
| Counter | Integer, zero or positive. | 0 |
| Reset strategy | never, yearly. | never |
| Default | Boolean — mark this series as the default for new documents of this type. | off |
| Enabled | Boolean — allow this series to be used. | on |
Renaming a slug updates the series row in place (preserving the
integer id and any references) and migrates the default_series
setting automatically if it pointed at the old slug. Deleting a
series does not remove existing documents; they keep their
numbers.
Document types
The Document types tab toggles optional document types and exposes the FatturaPA-specific bollo and ritenuta settings.
Document types card
| Toggle | Default | Description |
|---|---|---|
| Auto-issue credit note on WC refund | on | When a WooCommerce refund is created, automatically issue a credit note linked to the original invoice. |
| Enable proforma documents | on | Show a “Create proforma” button on the WC order screen and allow conversion to invoice. |
| Enable quote (preventivo) documents | on | Show a “Create quote” button on the WC order screen. Quotes are non-fiscal: a PDF is produced but no XML. |
FatturaPA — Italian B2B card
| Field | Default | Description |
|---|---|---|
| Bollo virtuale assolto | off | Emit DatiBollo (2,00 EUR virtual stamp) on invoices above EUR 77,47 when the obligation has been declared to the Agenzia delle Entrate. |
| Apply Ritenuta d’acconto | off | Compute and emit DatiRitenuta on invoices to Italian B2B buyers. |
| Default rate | 20.00 % | 0–100, step 0.01. |
| Tipo ritenuta | RT02 | RT01 (persone fisiche) or RT02 (persone giuridiche). |
| Causale pagamento | A | Single uppercase letter from the SDI 1.1.5.2 table (e.g. A = professional services). |
Templates
Pick one of three bundled PDF templates and customise its colours and typography.
| Template | Description |
|---|---|
| Minimal | Clean sans-serif layout with a teal accent. Default. |
| Classic | Serif typography with a coloured header band. Traditional look for professional services. |
| Modern | Two-column header and rounded cards. Suited to design-led brands. |
Additional fields:
| Field | Default | Notes |
|---|---|---|
| Primary colour | #1e8a8a | Native HTML5 colour picker; accent for headings, dividers and table headers. |
| Font | Site theme font (system stack) | One of: default, dejavusans, dejavuserif, dejavusansmono, helvetica, times, courier. The default value uses the site’s system font stack with DejaVuSans as the PDF fallback. |
| Text colour | #222222 | Default body-text colour. Muted captions and footers keep their lighter tone. |
The tab also embeds a live PDF preview (rendered against the
/wp-json/invoice-pilot/v1/preview-template REST endpoint) so you can
compare templates side-by-side before saving. Changing the radio
swaps the iframe immediately; the choice persists only when you press
Save template.
A read-only XML writers table sits beneath the preview, showing which envelope is emitted for each buyer country:
| Country | Writer |
|---|---|
IT Italy | FatturaPA v1.2 (FPR12) |
FR France | Factur-X (CII BASIC, hybrid PDF/A-3) |
DE Germany | XRechnung 3.0 (UBL) |
PL Poland | KSeF FA(2) v1-0E |
RO Romania | CIUS_RO 1.0.0 (UBL) |
ES Spain | Facturae 3.2.2 |
PT Portugal | SAF-T (PT) AuditFile excerpt |
DK Denmark | OIOUBL (NemHandel) |
FI Finland | Finvoice 3.0 |
AT Austria | ebInterface 6.1 |
GR / EL Greece | myDATA InvoicesDoc |
* Other (EU + extra-EU) | UBL 2.1 / PEPPOL BIS 3.0 |
The dispatcher is the invoice_pilot_xml_writer_for_country filter,
so host code can override per ISO.
VAT validation
VAT identifiers entered at checkout (and on any address screen that exposes the field) are run through a chain of validators. Each validator is enabled by an independent toggle and runs in order until one returns a positive result; both successful and negative answers are cached for the configured TTL.
| Validator | Default | Description |
|---|---|---|
| VIES (EU SOAP) | on | Cross-checks EU VAT IDs against the European Commission VIES service. |
| Per-country format | on | Offline regex validation per country. Always recommended as a fallback. |
| Field | Default | Range |
|---|---|---|
| Cache TTL (hours) | 24 | 1 – 720. Failed VIES lookups older than 6 hours are revalidated by the hourly cron. |
A read-only Cache state row reports the number of cached entries and how many have expired and are pending eviction.
Integrations
The Integrations tab renders one card per registered integration
provider. By default Invoice Pilot ships two providers; third-party
code can register additional ones through the
invoice_pilot_integration_providers filter.
SmartBill
Romanian invoicing provider. Credentials are encrypted at rest using the plugin’s symmetric crypto layer.
| Field | Default | Notes |
|---|---|---|
| Enable SmartBill | off | Push issued invoices to SmartBill as soon as they are emitted. |
| API username | empty | The username you use to sign in to SmartBill. |
| Token | empty | Paste your SmartBill API token. The stored value is encrypted; leave the field blank on subsequent saves to keep it. |
| CIF (company) | empty | Romanian company VAT code. |
| Series | empty | SmartBill series used for pushed invoices. |
When enabled, Invoice Pilot calls POST /SBORO/api/v2/invoice on
issuance, then pull_status to reconcile and void when an invoice
is cancelled.
Fatture in Cloud
Italian invoicing provider. OAuth tokens are stored encrypted at
rest. The daily invoice_pilot_refresh_fic_token cron refreshes the
access token automatically when the integration is enabled.
| Field | Default | Notes |
|---|---|---|
| Enable Fatture in Cloud | off | Push issued invoices to Fatture in Cloud as soon as they are emitted. |
| Client ID | empty | OAuth client identifier. |
| Access token | empty | Paste the OAuth access token. The stored value is encrypted; leave the field blank on subsequent saves to keep it. |
| Refresh token | empty | Same handling as the access token. |
| Company ID | 0 | Numeric company identifier in your Fatture in Cloud account. |
| Create customers | on | Automatically create a customer record on FIC when a new buyer is invoiced. |
Per the Fatture in Cloud product policy, Invoice Pilot does not submit FatturaPA to the SDI on your behalf. SDI submission is left to a separate manual step from inside your FIC account.
AI
The AI tab is split into two cards: Provider Configuration and Features. The plugin works fully without an API key; this tab adds optional AI-powered capabilities.
Provider Configuration
| Field | Notes |
|---|---|
| Provider | Anthropic Claude (default), OpenAI or Google Gemini. |
| API Key | Stored encrypted. The card shows a green Configured badge when a key is already on file. The “Get your API key from …” link points to the chosen provider’s console. |
| Model | Per-provider list (see table below). |
| Test Connection | Calls the provider’s messages / chat/completions endpoint with a one-token prompt and reports success or the upstream error. |
Models offered per provider:
| Provider | Models |
|---|---|
| Anthropic Claude | Claude Opus 4.7, Claude Sonnet 4.6 (recommended), Claude Haiku 4.5 (fast, cheap) |
| OpenAI | GPT-5, GPT-5 mini, GPT-4o, GPT-4o mini |
| Google Gemini | Gemini 2.5 Pro, Gemini 2.5 Flash, Gemini 2.5 Flash Lite |
Features
| Toggle | Default | Description |
|---|---|---|
| Smart-fill billing | off | Customers paste a free-form billing block at checkout; the model fills the structured form. |
| Smart-fill calls per hour | 5 | Per-session rate limit. |
| Compliance pre-flight check | off | Have the AI scan each invoice before issuance and flag potential issues. |
| Block issuance on error-level findings | off | When a critical issue is found, prevent the invoice from being issued. |
| Compliance calls per hour | 10 | |
| Translate line descriptions | off | Use AI to translate invoice lines into the buyer’s language. Polyglot-aware when the sibling plugin is installed. |
| Natural-language invoice search | off | Free-text queries on the Invoices admin page. |
| Search calls per hour | 10 |
Advanced
Retention & uninstall
| Field | Default | Range |
|---|---|---|
| Log retention (days) | 90 | 1 – 3650. Integration log entries older than this are purged by the daily cron. |
| Wipe data on uninstall | off | Drop all Invoice Pilot tables and options when the plugin is uninstalled. Destructive. Off by default. |
Maintenance actions
- Run log cleanup now — fires the
invoice_pilot_cleanup_logsaction immediately instead of waiting for the daily cron. - Purge validation cache — deletes every row from the VAT validation cache table.
A small Versions row at the bottom prints the current plugin version and database schema version.
Usage
Auto-issuing an invoice from a WooCommerce order
The default workflow requires no manual action.
- A customer places an order on WooCommerce. The checkout exposes
the VAT number and Tax code fields plus any
country-specific fields registered for the billing country (for
example Codice destinatario SDI and PEC on
ITorders). - When the order reaches the trigger status defined under
Settings → General → Trigger status (
processingby default), Invoice Pilot issues an invoice using the Default series (INVby default), persists an immutable JSON snapshot of the order, renders the PDF, generates the XML envelope for the buyer country, and pushes to any enabled integration. - The order screen gains an Invoice Pilot meta box that lists the issued documents with links to the PDF and XML, plus action buttons for Regenerate, Reissue, Void, Create credit note, Create proforma, Create quote and Push to provider.
Issuing manually
If automatic issuance is disabled or the order has not yet reached the trigger status, the order meta box exposes an Issue now button. The same flow applies — snapshot, PDF, XML, integration push — but it runs on demand.
Credit notes from refunds
When Auto-issue credit note on WC refund is on (the default), any
WooCommerce refund created against an order with an existing invoice
triggers a credit note in the CN series. The credit note links
back to the parent invoice and references it in the XML.
Proformas and quotes
When the corresponding toggles are on, the order screen also exposes Create proforma and Create quote buttons. Both produce non-fiscal documents — a PDF is rendered but no XML is generated for quotes. A proforma can be converted to an invoice with the Convert action, which re-numbers the document under the configured invoice series.
Sending an invoice to the customer
The plugin registers a Send Invoice Pilot invoice to customer
order action under WooCommerce’s standard order-actions dropdown,
which emails the PDF to the buyer using WordPress’s wp_mail().
Downloading documents
PDFs and XML envelopes are served from a publicly addressable but token-signed REST endpoint:
GET /wp-json/invoice-pilot/v1/download/{id}/{format}?token=…{format} is pdf or xml. The token is generated when the
document is issued and printed into the order meta box and the
Invoices list table.
Dashboard
Invoice Pilot → Dashboard opens the activity overview. A period bar offers four windows: 7 days, 14 days, 30 days (default) and 90 days. Five KPI cards display:
- Invoices (count)
- Net revenue
- VAT collected
- Avg value
- B2B / B2C split
Below the KPIs, two charts render time-series totals and the top
buyer countries. All figures are hydrated from
/wp-json/invoice-pilot/v1/dashboard?days=N.
Invoices list
Invoice Pilot → Invoices lists every issued document with status badges (issued, void, credit) and quick actions. When AI search is enabled, the search box accepts free-text queries (for example, “German invoices last month over 1,000 EUR”) that the configured provider translates into a list query.
Integration log
Invoice Pilot → Log records every integration push, response and
failure. Each row links to a single-event detail page where the full
request and response are shown (with credentials redacted). Old
entries are pruned by the daily invoice_pilot_cleanup_logs cron
according to the Log retention (days) setting.
Network admin (Multisite)
On a Multisite network, an additional Invoice Pilot Network page appears in the network admin sidebar. It aggregates invoice counts and totals across every sub-site that has Invoice Pilot active.
EU-27 invoicing
Invoice Pilot ships a registry of country-specific billing fields for every EU-27 member state. Each field is optional at checkout (the plugin does not force B2B-only data on a B2C order); validation fires only when the buyer country matches the field’s ISO.
The registry currently covers:
| Country | Fields |
|---|---|
IT Italy | ei_recipient_code (7 alphanumeric, default 0000000), ei_certified_email (PEC), fiscal_regime (RF01–RF19) |
FR France | siren (9 digits), siret (14 digits), chorus_pro_service_code |
DE Germany | steuernummer, ust_id, leitweg_id, hrb |
ES Spain | nif, face_oficina_contable, face_organo_gestor, face_unidad_tramitadora |
PT Portugal | nif (9 digits), atcud |
NL Netherlands | kvk_number (8 digits), btw_id |
BE Belgium | bce_number (10 digits) |
LU Luxembourg | — |
AT Austria | uid_nummer, firmenbuchnummer, steuernummer |
IE Ireland | — |
DK Denmark | cvr_number (8 digits), ean_location_number |
SE Sweden | organisationsnummer |
FI Finland | y_tunnus, ovt_code |
PL Poland | nip (10 digits), regon, ksef_id |
CZ Czech Republic | dic, ico (8 digits), data_box_id |
SK Slovakia | dic, ico (8 digits), data_box_id |
HU Hungary | tax_number, group_member_id |
SI Slovenia | vat_id, maticna_stevilka |
HR Croatia | oib (11 digits) |
RO Romania | cui |
BG Bulgaria | eik (9–13 digits), vat_id |
GR Greece | afm (9 digits), dou_code |
CY Cyprus | tic |
MT Malta | id_number |
LT Lithuania | company_code |
LV Latvia | registration_number |
EE Estonia | registry_code |
The block-checkout integration registers fields under the
invoice-pilot/... namespace through the Additional Checkout Fields
API. By default only the Italian fields are exposed in the block
checkout to avoid overwhelming non-Italian shoppers; the All EU-27
fields at checkout toggle in General turns on the full set.
The legacy shortcode checkout always renders the complete registry
filtered by the selected billing country.
Country fields are persisted on the order, copied into the immutable
invoice snapshot, and consumed by the XML writers — for example the
Italian ei_recipient_code becomes CodiceDestinatario /
PECDestinatario in the FatturaPA envelope, while the German
leitweg_id becomes BuyerReference / EndpointID 0204 in
XRechnung.
Integrations
SmartBill
SmartBill (Romania) is wired into the plugin’s IntegrationManager
through the invoice_pilot_integration_providers filter and exposes
the standard provider interface: push, pull_status, void and
test_connection.
- Push maps the invoice snapshot to the SmartBill JSON schema
and calls
POST /SBORO/api/v2/invoicewith the configured CIF and series. - Status sync reconciles draft / issued / paid state when the fifteen-minute retry cron runs.
- Void cancels a previously pushed invoice on SmartBill when the source invoice is voided in WordPress.
All actions are logged to the Integration log. Failures are queued
and retried by the invoice_pilot_retry_integrations cron.
Fatture in Cloud
Fatture in Cloud (Italy) follows the same provider interface and
maps the invoice snapshot to the entity / items_list shape
expected by FIC’s issued-document endpoint. Italian country-specific
fields are mapped explicitly:
ei_recipient_code→ei_codeei_certified_email→certified_email- buyer VAT / tax-code / province / country → corresponding
entitykeys
OAuth credentials are encrypted at rest. The daily
invoice_pilot_refresh_fic_token cron refreshes the access token
when the integration is enabled. Setting Create customers to
on causes the integration to create a new customer record in FIC
on the first invoice for a buyer.
Invoice Pilot does not submit FatturaPA to the SDI on your behalf. SDI submission is left to a separate manual step from inside your Fatture in Cloud account.
AI smart-fill
The AI layer is fully optional. Without a configured API key the plugin still issues invoices, renders PDFs and XML, validates VAT, and pushes to integrations — only the four AI features below are unavailable.
Three providers are supported:
| Provider | Default model | API key URL |
|---|---|---|
| Anthropic Claude | claude-haiku-4-5-20251001 | console.anthropic.com |
| OpenAI | gpt-5 | platform.openai.com |
| Google Gemini | gemini-2.5-pro | aistudio.google.com |
The API key is stored encrypted at rest using the plugin’s symmetric crypto layer. Pressing Test Connection issues a minimal request to the chosen endpoint and surfaces the upstream error if the credentials are wrong.
Four features can be toggled independently once a key is on file:
- Smart-fill at checkout — a “Paste billing details” textarea appears at checkout. The model parses the free-form text and fills the structured WooCommerce billing form, including the country-specific fields. Rate-limited per session.
- Compliance pre-flight check — every invoice is run through the model just before issuance, with the option to block issuance on error-level findings when a critical issue is detected (for example, an Italian B2B invoice missing the SDI recipient code).
- Line auto-translate — invoice line descriptions are translated into the buyer’s language. When the sibling Polyglot plugin is installed, the translation pipeline is delegated to it.
- Natural-language invoice search — the search box on the Invoices admin page accepts free-text queries that the model translates into a list query.
Each feature has its own per-hour rate limit.
Hooks and filters
Centralised hook names live in the \InvoicePilot\Core\Hooks class.
The full list:
| Hook | Type | Purpose |
|---|---|---|
invoice_pilot_redact_keys | filter | Extra keys to redact from logged payloads. |
invoice_pilot_xml_writer_for_country | filter | Override the XML writer per buyer ISO. Two arguments: current writer, ISO. |
invoice_pilot_validator_chain | filter | Override or extend the VAT validator chain. |
invoice_pilot_integration_providers | filter | Register additional integration providers. |
invoice_pilot_country_fields | filter | Register additional country-specific checkout fields. |
invoice_pilot_booted | action | Fires after the plugin has booted. Passes the singleton. |
invoice_pilot_register_modules | action | Module registration hook. |
invoice_pilot_invoice_issued | action | Fires after a new invoice is issued. |
invoice_pilot_invoice_rendered | action | Fires after the PDF or XML is rendered. |
invoice_pilot_integration_pushed | action | Fires after a successful integration push. |
invoice_pilot_integration_failed | action | Fires after a failed integration push. |
invoice_pilot_cleanup_logs | action | Daily cron — purges old integration log entries. |
invoice_pilot_retry_integrations | action | Fifteen-minute cron — retries failed pushes. |
invoice_pilot_revalidate_vies | action | Hourly cron — revalidates stale VIES cache entries. |
invoice_pilot_render_integration_tab | action | Fired from the Integrations settings tab so providers can render their own settings cards. |
invoice_pilot_refresh_fic_token | action | Daily cron — refreshes the Fatture in Cloud access token. |
Registering a custom XML writer:
add_filter(
'invoice_pilot_xml_writer_for_country',
function ( $writer, $iso ) {
if ( 'NL' === $iso ) {
return new My_Custom_Nl_Writer();
}
return $writer;
},
20,
2
);Registering a custom integration provider:
add_filter(
'invoice_pilot_integration_providers',
function ( array $providers ) {
$providers[] = new My_Custom_Provider();
return $providers;
}
);FAQ
Does Invoice Pilot submit FatturaPA to the SDI?
No. Invoice Pilot generates the FatturaPA XML and stores it on the order; SDI submission is intentionally left to a separate manual step (or to the Fatture in Cloud integration on your account).
Can I add a writer for a country that isn’t built in?
Yes. Hook into invoice_pilot_xml_writer_for_country and return
your own implementation of \InvoicePilot\Modules\Xml\XmlWriterInterface.
Does it work on the WooCommerce block checkout?
Yes. Country-specific fields are registered through the WooCommerce 8.6+ Additional Checkout Fields API, so they appear in both the block checkout and the legacy shortcode checkout. On WooCommerce versions older than 8.6, only the legacy filter path is used.
Does it work on WordPress Multisite?
Yes. Each sub-site has its own tables, settings and numbering
counters. A network admin page under Network Admin → Invoice
Pilot Network aggregates invoice counts across the network. On
new sub-sites, tables and default series are created automatically
through the wp_initialize_site hook.
Are credentials encrypted?
Yes. SmartBill tokens, Fatture in Cloud OAuth tokens and the AI API
key are encrypted at rest via \InvoicePilot\Core\Crypto. Leaving
a token field blank on the next save keeps the existing stored
value.
What happens to my data if I delete the plugin?
Nothing, unless you opt in. The default for Advanced → Wipe data
on uninstall is off, so tables, options, integration logs and
the validation cache are preserved across deactivation /
reactivation. Toggle the option on if you want the
uninstall.php routine to drop everything when WordPress deletes
the plugin.
Where can I get an API key for the AI features?
Each provider has its own console: Anthropic at console.anthropic.com , OpenAI at platform.openai.com , Google AI Studio at aistudio.google.com . The AI tab links directly to the chosen provider’s console.
Do I need an AI key for the plugin to work?
No. The AI features (smart-fill, compliance check, line translation, natural-language search) are optional. The core invoicing engine — document lifecycle, PDF and XML generation, VAT validation, integrations, dashboard — runs without an API key.
Troubleshooting
The invoice isn’t issued when the order moves to Processing
Check Settings → General → Trigger status. The default is
processing; if you have customised it (for example to
completed), the auto-issue routine only fires on the configured
status. You can also press Issue now from the order meta box
to issue manually regardless of the trigger.
The block checkout shows too many country fields
The default exposes only the Italian SDI fields in the block checkout. If you see the full EU-27 list, open Settings → General and turn off All EU-27 fields at checkout. The legacy shortcode checkout always filters by the selected billing country, so this setting only affects the block checkout.
VAT validation hangs or times out
The VIES service is occasionally slow or unavailable. The plugin
keeps a per-VAT cache for the configured TTL (24 hours by default)
and revalidates stale entries hourly through the
invoice_pilot_revalidate_vies cron. If VIES is offline, the
Per-country format validator still accepts well-formed numbers.
You can also raise the cache TTL under Settings → VAT validation.
The dashboard shows no data
The dashboard SQL relies on JSON_EXTRACT / JSON_UNQUOTE against
the immutable invoice snapshot column. Make sure your database
server is MySQL 5.7+ or MariaDB 10.2+. If the period bar shows the
right window but the cards remain on --, open
/wp-json/invoice-pilot/v1/dashboard?days=30 directly and check
the response — REST authentication failures appear as
rest_forbidden.
Integration push fails
Open Invoice Pilot → Log and click the failed entry. The
single-event page shows the full request / response (with
credentials redacted) and the upstream error message. The failed
entry is automatically retried by the
invoice_pilot_retry_integrations cron every fifteen minutes; you
can also press Push to provider in the order meta box to retry
immediately.
Test Connection on the AI tab reports an error
The message returned in red comes straight from the provider’s endpoint. Common causes:
- An invalid or revoked API key — generate a new one and paste it into the API Key field, then save.
- A model name that the account does not have access to — pick a different model in the dropdown.
- Network egress blocked by the host — confirm outbound HTTPS to
api.anthropic.com,api.openai.comorgenerativelanguage.googleapis.comis allowed.
Email alerts to the customer are not arriving
Customer invoice emails are sent through WordPress’s wp_mail()
function. If no email arrives, the issue is almost always with the
site’s mail configuration rather than with Invoice Pilot. Install
a transactional mail plugin (for example, one that routes WordPress
mail through SMTP) and trigger the Send Invoice Pilot invoice to
customer order action again from a test order.