=== Age Verification 18+ for WooCommerce ===
Contributors: catcode
Tags: age verification, altersverifikation, woocommerce, age gate, jugendschutz
Requires at least: 6.2
Tested up to: 7.1
Requires PHP: 7.4
Stable tag: 1.0.1
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Age verification for WooCommerce: a minimum age per product or category, a date-of-birth gate, hard blocking on both checkouts, and a verification log.

== Description ==

A shop that sells alcohol, tobacco, vapes, knives, pyrotechnics, hazardous chemicals or other regulated goods has to establish the customer's age before it hands them over. Most age plugins put a single splash screen in front of the whole website; that is not what a mixed shop needs, and it is not what ends up in the order record.

This plugin works the other way round. The age belongs to the goods: you give a product category (or a single product) its minimum age, and from then on the shop asks only when something in the cart actually requires it — on the product page, on the cart, and before the order is placed. The answer is written into the order and into a log the shop can show when asked whether it checked.

**What it is not.** Typing a date of birth into a browser is a declaration by the customer, not an identity check. German law treats a sale as mail order (Versandhandel) unless there is personal contact between supplier and buyer or technical or other precautions ensure that nothing is shipped to children and young people (§ 1 (4) JuSchG), and tobacco, nicotine products and e-cigarettes must not be offered or delivered to minors by mail order (§ 10 (3) and (4) JuSchG). Whether a given process counts as such a precaution is a question for your legal adviser, not for a plugin. What the plugin does is document the shop's due diligence, stop orders that fail the rule, and — in Pro — let you close the gap where it can actually be closed: on delivery, with a shipping method that checks the ID on handover. The plugin states this plainly rather than promising compliance.

Free:

* Minimum age per product, per product variation and per product category, inherited down the category tree. A single product can be exempted from its category rule.
* The whole shop can be gated instead, for shops that sell nothing but regulated goods.
* Age gate with a real date of birth (day / month / year), or a one-click confirmation if you prefer the lighter variant.
* The order is blocked server side on the **classic checkout and the block (Store API) checkout** — not only by the dialog, so a closed dialog or a disabled script changes nothing.
* Optional block on adding a restricted product to the cart, and an optional gate on the product page.
* "18+" badge on restricted products in the catalogue and on the product page.
* Verification log: what was required, what was declared, the date of birth, the result, the order, the country, and a reference number that ties the rows to the order. The IP is hashed by default.
* The confirmation is written into the order, with an order note and a panel on the order screen (HPOS and the legacy screen).
* The answer is remembered for a period you choose, and the gate locks after a number of failed attempts, with an optional page to send a locked-out visitor to.
* Custom heading, text and rejection text, with {age} replaced by the required age.
* Translations: English and German (de_DE).

Pro (licence from catcode.com.ua):

* Minimum age per delivery country, with starting presets for Germany, Austria and Switzerland. A country rule can raise the age for a category — never lower it.
* Shipping methods limited for restricted orders: leave only the carriers that check the ID on handover, or pickup in the shop.
* Payment methods hidden for restricted orders, so a parcel cannot be paid for in a way that lets it be dropped at the door.
* A delivery age-check note added to the order and to the e-mails, for the warehouse and the carrier.
* CSV export of the verification log for an audit or an authority request, with a date range.
* Log retention: rows older than the period you set are deleted automatically.
* Your logo and accent colour in the age gate.

== Installation ==

1. Upload the plugin and activate it.
2. WooCommerce → Age verification → Rules: give every product category that holds regulated goods its minimum age. Single products can override it on the product edit screen.
3. WooCommerce → Age verification → Settings: choose whether only restricted products are protected or the whole shop, how the customer answers, and how long the answer is remembered.
4. Switch "Age gate" on and place a test order with a restricted product — on both the classic and the block checkout if the shop offers both.

== Frequently Asked Questions ==

= Does this make my shop legally compliant? =
No plugin can promise that. It records that the shop asked, what was answered and when, and it prevents an order that fails the rule. Where the law demands real identification, the check has to happen at handover — the Pro shipping rules exist to force exactly that. Confirm the ages and the procedure with your legal adviser.

= Which ages should I set? =
That depends on the goods and the delivery country, and it is the shop owner's responsibility. For orientation, from the official texts (09/2026):

* Germany — § 9 JuSchG: beer, wine and sparkling wine from 16, other alcoholic drinks from 18. § 10 JuSchG: tobacco, nicotine products and e-cigarettes from 18, including mail order.
* Austria — youth protection is state law (for example Vienna, § 11a Wiener Jugendschutzgesetz 2002, for public places and events: alcohol from 16, drinks containing distilled alcohol from 18). § 2b TNRSG: tobacco and related products from 18; § 2a TNRSG prohibits mail-order sales of tobacco and related products altogether.
* Switzerland — Art. 14 LMG: alcoholic drinks from 16. Art. 41 AlkG: distilled spirits from 18. Art. 23 TabPG: no tobacco products or e-cigarettes to minors. Art. 64 ChemV: hazardous chemicals of groups 1 and 2 only to persons with full legal capacity.

The country presets in Pro set 18+ for everything restricted that ships to the country — the strictest reading — so you can lower a category on purpose where the law allows. They are a starting point, not legal advice.

= Does it work with the block checkout? =
Yes. The rule is enforced through the Store API as well: the cart block and the checkout block show the error, and the order is refused while it is being built. The dialog itself is plain HTML in the footer, so it appears on both checkouts without a separate build.

= A customer closed the dialog. Can they still order? =
No. The dialog is only the convenient way to answer. Every guard is server side, so closing it, blocking the script or calling the Store API directly all end in the same refusal.

= Is the date of birth personal data? =
Yes, and it is treated as such: it is stored with the order and in the log because that is the point of the record, the IP is hashed by default (or not stored at all, your choice), and Pro can delete log rows automatically after a period you set.

= What happens when I delete the plugin? =
The verification log survives, because it is the evidence that the shop asked. Define `CCAV_DELETE_DATA` as true in wp-config.php before deleting if you really want everything removed.

= Does it work with product variations? =
Yes. A variation can carry its own minimum age; without one it inherits from the product, and the product from its categories.

= Free and Pro =
The free version is complete for a shop that needs to ask, block and keep a record. Pro features are unlocked with a licence key from catcode.com.ua. The 7-day trial starts only when you click it. A purchased licence keeps its Pro features after the term ends — only updates and support stop.

== Changelog ==

= 1.0.1 =
* Renamed to "Age Verification 18+ for WooCommerce".
* Fix: the failed-attempt limit and the page for locked-out visitors now work for a first-time guest with an empty cart (the WooCommerce session is started when the gate records an answer).
* Fix: the age-verification order note is now written on the classic checkout too (it used to be dropped because the order had no id yet).
* Fix: retrying the block checkout no longer adds the order note, the delivery note and the log row twice.
* Fix: with a country rule (Pro), the checkout message now shows every product with the age that actually applies to it, instead of the base age next to a higher requirement.
* Country rules are now applied per product: a rule for a category also restricts products of that category that had no age before; a rule for "everything restricted" still only raises goods that already need an age; a product exempted with 0 stays exempt.
* One-click method: answering "No" now locks the gate on the server as well, not only in the browser.
* Admin: an inherited age is shown in the category list, on the category edit screen, on the Rules tab and as the placeholder of the product and variation field.
* Country presets relabelled with the statutory ages and their sources (JuSchG, TNRSG, LMG, AlkG, TabPG, ChemV); readme wording on what a date-of-birth check is and is not.

= 1.0.0 =
* First release.
