=== Encadena SIF ===
Contributors: farowp
Tags: verifactu, invoicing, vat, woocommerce, aeat
Requires at least: 6.2
Tested up to: 7.1
Requires PHP: 7.4
Stable tag: 1.4.0
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Verifactu (Veri*factu) invoices for WooCommerce: chained record, hash, tax QR, PDF and AEAT submission with your own certificate.

== Description ==

Encadena SIF is an independent plugin. Veri*factu (Verifactu) is the invoice verification system of the
Spanish Tax Agency (AEAT): this plugin is not affiliated with, endorsed by or sponsored by the AEAT.

Encadena SIF turns every WooCommerce order into a Spanish billing record (registro de facturación) that follows
Royal Decree 1007/2023 and Order HAC/1177/2024: it creates the record, chains it with its SHA-256 hash, prints the
tax QR and either sends it to the Spanish tax agency (VERI*FACTU mode) or keeps it chained locally (non VERI*FACTU
mode, with event records).

It is a **Verifactu** plugin: Verifactu is how everyone writes it, and Veri*factu is the official name the AEAT uses.
Both are the same regulation, and this plugin works either way: with a certificate it submits to the AEAT, and without
one it keeps the chain in the shop.

The free plugin is complete for one shop and one tax ID: issuing, voiding, corrective invoices, QR, PDF and
submission with the shop's own certificate. Nothing is held back behind a licence.

**What it does, and why it is built this way**

* The hash reproduces **exactly** the official AEAT examples (three cases from the technical specification v0.1.2),
  and the QR reproduces the four official URL variants.
* Records are **immutable**: they are only inserted, never updated or deleted. The submission state lives in a
  separate table, so the fiscal content of a record never changes.
* **Independent chains per taxpayer** and correlative numbering per series and tax ID.
* The certificate is stored **outside the public directory**, encrypted, in `uploads/encadena-sif-certs/`, and its
  password is encrypted too: it is read from the `VF_CERT_PASS` constant in `wp-config.php` when you define it, or
  from the encrypted copy the plugin keeps next to the certificate.
* **PDF invoice with the QR**: with *PDF Invoices & Packing Slips for WooCommerce* active, the invoice carries the
  record number and date, the customer tax ID, the issuer's fiscal data and the verification QR.
* Compatible with WooCommerce High-Performance Order Storage (HPOS).

**What the shop owner never has to fill in**

The system identifier, its version, the producer and the responsible declaration travel with the plugin. The shop
only configures its own data: tax ID, legal name, series, when to invoice, and its certificate.

== Installation ==

1. Upload the plugin folder to `/wp-content/plugins/`, or install it from the zip.
2. Go to **Encadena SIF → Issuer** and enter the tax ID, the legal name and the series.
3. In **Certificate**, add `define('VF_CERT_PASS', '…');` to `wp-config.php` and upload your `.p12`.
4. In **Invoicing**, choose the mode, the environment (start with **AEAT test**) and when an order is invoiced.
5. Place a test order and move it to the status that invoices: the record appears in **Records**.

== Frequently Asked Questions ==

= Is this electronic invoicing (factura electrónica)? =

No. This covers the billing record system (Veri*factu). Business-to-business electronic invoicing is a different
regulation (Law 18/2022 and Royal Decree 238/2026).

= Do I need an AEAT "homologation"? =

There is no such homologation. The manufacturer signs a responsible declaration (art. 15 RRSIF), which is
reproduced inside the plugin, in the **Help** tab.

= What happens if I uninstall the plugin? =

Settings are removed, **billing records are not**: the law requires keeping them.

= Does it work without a certificate? =

It issues and chains records but cannot submit them. The panel warns about it in the header and in the summary.

= Does it send data anywhere else? =

Only to the two services described in **External services**: the AEAT endpoint you select (test or production), and
only if you enable it, your own Telegram bot. Nothing else leaves the site.

== External services ==

The plugin connects to two external services. Both are optional: without a certificate it never contacts the AEAT,
and the Telegram notice stays off until a bot token and a chat are entered.

= Spanish Tax Agency (AEAT) — Veri*factu =

* **What is sent:** the billing record (invoice number and date, amounts and tax breakdown, the customer's tax ID and
  name, the previous record's hash and the hash of the record itself). No other data of the shop or of the customer
  is sent, and nothing is sent while the plugin is in non VERI*FACTU mode.
* **When:** only when the mode is VERI*FACTU and an order reaches the status you chose, and when you press
  “Test connection” in the panel.
* **Where:** `https://prewww1.aeat.es/wlpl/TIKE-CONT/ws/SistemaFacturacion/VerifactuSOAP` (test) or
  `https://www1.agenciatributaria.gob.es/wlpl/TIKE-CONT/ws/SistemaFacturacion/VerifactuSOAP` (production).
* **How it identifies itself:** with the certificate you upload (mutual TLS). There is no shared credential and no
  account with the AEAT.
* **Terms of service:** https://sede.agenciatributaria.gob.es/Sede/aviso-legal.html
* **Privacy policy:** https://sede.agenciatributaria.gob.es/Sede/proteccion-datos.html

= Telegram (optional notices) =

* **What is sent:** the text of the notice (invoice issued, submission rejected, summary) and the chat identifier
  you configure. No customer data beyond what the notice text already shows.
* **When:** only if you enter a bot token and a chat ID in the settings, and only when one of those events happens.
* **Where:** `https://api.telegram.org/bot<token>/sendMessage`, the official Telegram Bot API.
* **Terms of service:** https://telegram.org/tos
* **Privacy policy:** https://telegram.org/privacy

The plugin does not send telemetry, does not contact any update server of its own and does not share data with any
other third party.

== Screenshots ==

1. Configuration: what is missing and what is already in place, plus the four-step guide.
2. Issuer and invoicing: tax ID, series and the status that triggers the invoice.
3. Billing records with their hash, their AEAT status and a link to the order.

== Changelog ==

= 1.4.0 =
* New name: the plugin is now **Encadena SIF**. Only the visible name, the slug and the text domain change; the settings, the billing records and the certificate stay where they were, so
  updating does not lose anything.
* The name shown inside the plugin (menu, screens, schedule label and notices) is the same as in the directory.
* The locale files are renamed to the new text domain.
* Scripts are enqueued with `wp_enqueue_script()` / `wp_add_inline_script()`: no raw `<script>` tags are printed.
* Every output is escaped (`esc_html`, `esc_attr`, `esc_url`, `wp_kses_post`).
* All functions, options, constants and tables carry the plugin prefix.
* Requests to the AEAT and to Telegram go through the WordPress HTTP API (`wp_remote_post()`); the client
  certificate is attached with the `http_api_curl` hook.
* The certificate is stored in `uploads/encadena-sif-certs/`, not in `wp-content/`; the file of an older installation
  is moved there automatically on the first upload or on the first request.
* The settings are sanitized with a callback of their own, and the certificate path is checked against the folder
  the plugin uses (realpath, no traversal).
* Secrets on disk (certificate password, Telegram token, SMTP password) are encrypted with AES-256-GCM and a local
  key file. No external process is started in any system.
* External services (AEAT and Telegram) are documented in the readme: what is sent, when, and their terms and
  privacy links.

= 1.3.2 =
* First public release. The readme also spells it "Verifactu", as most people write it, so the search finds it.

= 1.3.1 =
* Initial submission. The interface is in English and fully translatable (456 strings); the Spanish
  translation is published on translate.wordpress.org.

= 1.2.0 =
* Internal build. The plugin is free and complete for one shop and one tax ID; the paid edition (Encadena SIF
  SIF Pro) will add multi-shop management and support.
* Distribution and licence metadata prepared for the WordPress.org directory.

= 1.1.1 =
* Complete responsible declaration: address, contact email, legal representative, place of signature and
  availability come from the producer and travel with the plugin.
* The panel shows the whole document and warns about missing data.
* The declaration can be downloaded as a PDF from the Help tab.

= 1.1.0 =
* Step-by-step, collapsible guide in every panel tab.
* Warning when the tax ID and the name do not match (the AEAT 4104 error).
* Warning for a certificate saved on disk but not linked to the settings.
* Red warning while in Production, so nobody declares by accident.

= 1.0.2 =
* AEAT failures (SOAP `<Fault>`) are stored as rejections with their code and reason.
* Added the hint for error 4104.

= 1.0.1 =
* Fixed: the certificate was uploaded and encrypted but the panel kept saying "No certificate".
* Uploading a certificate removes the other extension (.p12 or .pfx).
* The panel shows the certificate holder and tax ID without the full distinguished name.

= 1.0.0 =
* Own tabbed panel (Summary, Issuer, Invoicing, Certificate, Records, Help) with status checks.
* Every invoicing option explained on screen.
* Producer data and the responsible declaration no longer asked from the shop.
* PDF invoice with the tax QR and the verification texts.

= 0.1.0 =
* First development version: record core (hash verified against the official AEAT examples), immutable store,
  settings, diagnostics panel and responsible declaration.

== Upgrade Notice ==

= 1.3.2 =
First public release on WordPress.org.
