Title: Pay4All Age Verification for WooCommerce &amp; Pay4All Shop
Author: pay4all
Published: <strong>16 de juliol de 2026</strong>
Last modified: 22 de juliol de 2026

---

Cerca extensions

![](https://ps.w.org/pay4all-age-verification/assets/banner-772x250.png?rev=3611581)

![](https://ps.w.org/pay4all-age-verification/assets/icon-256x256.png?rev=3610333)

# Pay4All Age Verification for WooCommerce & Pay4All Shop

 Per [pay4all](https://profiles.wordpress.org/pay4all/)

[Baixa](https://downloads.wordpress.org/plugin/pay4all-age-verification.1.3.1.zip)

 * [Detalls](https://ca.wordpress.org/plugins/pay4all-age-verification/#description)
 * [Ressenyes](https://ca.wordpress.org/plugins/pay4all-age-verification/#reviews)
 *  [Instal·lació](https://ca.wordpress.org/plugins/pay4all-age-verification/#installation)
 * [Desenvolupament](https://ca.wordpress.org/plugins/pay4all-age-verification/#developers)

 [Suport](https://wordpress.org/support/plugin/pay4all-age-verification/)

## Descripció

**Pay4All Age Verification** blocks any order containing age-restricted products
until the customer has uploaded a valid ID (recto + verso) and/or two selfies. Photos
are captured either directly on the customer’s desktop or, more commonly, through
a QR code that hands off to their smartphone.

The plugin plugs into **Pay4All Shop** (pay4all-form) and **WooCommerce**. Install
it alongside either storefront and it will only surface where a product is flagged
as age-restricted. The same setting screen (`Pay4All AGE > Paramètres`) drives both
integrations — a merchant running Pay4All Shop AND WooCommerce configures the verification
once, gets consistent behaviour everywhere.

#### Drag-drop step order

The two capture steps (ID card front/back and selfies) can be reordered by drag-
and-drop from `Pay4All AGE > Paramètres > Documents à demander > Ordre d'affichage`.
The chosen order applies to both Pay4All Shop and WooCommerce checkouts.

#### WooCommerce support

The WooCommerce integration (product-level «Requires age verification» checkbox,
QR-code checkout panel, order-screen photo viewer) is provided by the paid **Pay4All
Pro** add-on, distributed through pay4all.ch. Pay4All Age itself remains free ; 
Pay4All Pro simply wires it into WooCommerce.

#### How it works

 1. Merchant ticks _Requires age verification_ on any product edit screen (Pay4All 
    Shop product).
 2. When a customer adds such a product to their form, a panel appears in the KYC step
    showing a QR code.
 3. Customer scans the QR with their phone -> the mobile capture page opens -> they
    take the required photos with their phone camera.
 4. The desktop form polls the server every 4 seconds and unlocks automatically when
    every required slot is filled — no page refresh needed.
 5. On order submit, the encrypted photos are moved from the session bucket to the 
    order-scoped bucket, and are only decrypted on demand by an admin from the order
    edit screen.

#### Security

 * Photos are encrypted with **AES-256-GCM** using a per-order (or per-user) subkey
   derived via HMAC-SHA256 from a master key.
 * Ciphertexts live in a private folder guarded, so they are never web-servable.
 * Admin decryption endpoint is nonce-protected and requires the `edit_users` capability.
 * Photos are auto-purged when the order (or user) is permanently deleted.

#### WPML / Polylang

Multilingual-aware : when the _Requires age verification_ flag is set on a source
product, every translation is treated as age-restricted too — even if the flag hasn’t
been mirrored to the translation.

#### Available languages

Français (fr_FR), Deutsch (de_DE), Italiano (it_IT), English (en_US).

### External services

This plugin does not connect to any external service. Everything runs on the site:
photo capture, encryption, storage and admin decryption are all local. No data is
sent to any third-party server.

### Source code

The complete, non-minified source of this plugin is bundled inside the ZIP itself.
Every PHP, CSS and JavaScript file is human-readable and directly editable. No compiler,
transpiler or bundler is required to work on this plugin.

## Captures

[⌊Product edit screen : the Requires age verification checkbox, added right next
to the price row on Pay4All Shop products.⌉⌊Product edit screen : the Requires age
verification checkbox, added right next to the price row on Pay4All Shop products
.⌉[

Product edit screen : the _Requires age verification_ checkbox, added right next
to the price row on Pay4All Shop products.

[⌊Customer checkout with an age-restricted product in the cart : the KYC panel appears
in the « Vérification d'âge » step with the QR code + status of each photo slot.⌉⌊
Customer checkout with an age-restricted product in the cart : the KYC panel appears
in the « Vérification d'âge » step with the QR code + status of each photo slot.⌉[

Customer checkout with an age-restricted product in the cart : the KYC panel appears
in the « Vérification d’âge » step with the QR code + status of each photo slot.

[⌊Mobile capture page (loaded from the QR) : native camera capture for ID recto /
verso and selfies, live upload progress, encrypted at rest before storage.⌉⌊Mobile
capture page (loaded from the QR) : native camera capture for ID recto / verso and
selfies, live upload progress, encrypted at rest before storage.⌉[

Mobile capture page (loaded from the QR) : native camera capture for ID recto / 
verso and selfies, live upload progress, encrypted at rest before storage.

[⌊Admin lightbox : merchant clicks the shield icon on the order edit screen — the
encrypted photos are streamed, decrypted on-the-fly, and displayed side-by-side 
without being written back to disk.⌉⌊Admin lightbox : merchant clicks the shield
icon on the order edit screen — the encrypted photos are streamed, decrypted on-
the-fly, and displayed side-by-side without being written back to disk.⌉[

Admin lightbox : merchant clicks the shield icon on the order edit screen — the 
encrypted photos are streamed, decrypted on-the-fly, and displayed side-by-side 
without being written back to disk.

[⌊Settings page : merchant chooses required documents (ID / selfies / both), OR /
AND mode, purge delay, and can override the customer-facing texts in each activated
language.⌉⌊Settings page : merchant chooses required documents (ID / selfies / both),
OR / AND mode, purge delay, and can override the customer-facing texts in each activated
language.⌉[

Settings page : merchant chooses required documents (ID / selfies / both), OR / 
AND mode, purge delay, and can override the customer-facing texts in each activated
language.

## Instal·lació

 1. Upload the plugin to `/wp-content/plugins/pay4all-age-verification/` or install
    via _Plugins > Add New_.
 2. Activate it from the _Plugins_ menu.
 3. Open _Pay4All AGE > Paramètres_ to tune what documents you require and to override
    the customer-facing texts if needed.
 4. On each product that requires an age check, tick the _Requires age verification_
    checkbox on the product edit screen (Pay4All Shop product).

## PMF

### Do I need Pay4All Shop or WooCommerce?

Yes. Pay4All Age Verification is a companion plugin — it plugs into either **Pay4All
Shop** (free, ships the form-based checkout) or **WooCommerce** (via the paid Pay4All
Pro add-on). On a bare WordPress install without either, the plugin stays dormant
and shows an admin notice on the Plugins screen.

### How are photos encrypted?

**AES-256-GCM** with a per-order (or per-user) subkey derived via HMAC-SHA256 from
a master key. The master key is generated once and stored in `wp-content/uploads/
p4all-age-secure/age.key` (mode 0600). Ciphertexts live in the same private folder,
guarded by `.htaccess`, `index.php` and `web.config` so they are never web-servable—
a direct URL always returns 403 / 404. See the _Security_ section above for the 
full threat model.

### Where is the master encryption key stored?

Outside the database, in `wp-content/uploads/p4all-age-secure/age.key`. This means
a stolen SQL dump alone is not enough to decrypt the photos — the attacker would
also need read access to that specific file. Please make sure your backup strategy
either encrypts `wp-content/uploads/p4all-age-secure/` or excludes it entirely from
the backup archive.

### What happens to the photos when an order is deleted?

They are auto-purged. Both the WooCommerce order lifecycle (`woocommerce_delete_order`
hook) and Pay4All Shop order deletion trigger `KycStorage::purge_order()`, which
removes every encrypted blob and the order-scoped directory. A daily cron also purges
session-scoped buckets older than the configured TTL (default 24 h).

### What happens if a user account is deleted?

The `delete_user` hook fires `KycStorage::purge_user()` — every stored user photo(
recto / verso / selfie_1 / selfie_2) is removed together with the user record. GDPR-
friendly by default.

### Does the mobile capture page work on all phones?

The page uses the native `<input type="file" accept="image/*" capture="…">` API —
supported by Safari (iOS 6+), Chrome, Firefox, Edge on both Android and iOS. On 
the desktop side, the QR code is generated with a pure-JS library (no external service
call) and the pairing is polled every 4 seconds via a REST endpoint scoped to the
session token.

### Does it work with WPML / Polylang?

Yes. When a product’s _Requires age verification_ flag is ticked on a source-language
product, every translation is treated as age-restricted too — even if the flag hasn’t
been mirrored to the translation post. Same behaviour on WooCommerce products via
Pay4All Pro.

### Which languages ship out of the box?

French (fr_FR), German (de_DE), Italian (it_IT) and English (en_US). Every customer-
facing string is also overridable per-language from the settings page — merchants
can rewrite the KYC panel copy without touching a `.po` file.

### Does the plugin contact any external service?

No. Photo capture, encryption, storage and admin decryption are all local — nothing
leaves the site. The QR code is generated client-side ; the mobile page polls only
your own WordPress REST API.

## Ressenyes

No hi ha ressenyes per a aquesta extensió.

## Col·laboradors i desenvolupadors

«Pay4All Age Verification for WooCommerce & Pay4All Shop» és programari de codi 
obert. La següent gent ha col·laborat en aquesta extensió.

Col·laboradors

 *   [ pay4all ](https://profiles.wordpress.org/pay4all/)

[Traduïu «Pay4All Age Verification for WooCommerce & Pay4All Shop» a la vostra llengua.](https://translate.wordpress.org/projects/wp-plugins/pay4all-age-verification)

### Interessats en el desenvolupament?

[Navegueu pel codi](https://plugins.trac.wordpress.org/browser/pay4all-age-verification/),
baixeu-vos el [repositori SVN](https://plugins.svn.wordpress.org/pay4all-age-verification/),
o subscriviu-vos al [registre de desenvolupament](https://plugins.trac.wordpress.org/log/pay4all-age-verification/)
per [fisl de subscripció RSS](https://plugins.trac.wordpress.org/log/pay4all-age-verification/?limit=100&mode=stop_on_copy&format=rss).

## Registre de canvis

#### 1.3.1

 * Fix : the resend « Documents received » screen didn’t paint on the desktop copy
   of the mobile page after the customer uploaded from their phone. Root cause :
   the resend token was cleared the instant the last photo landed, so the desktop
   poll got 410 and never observed the « satisfied » state. The token now stays 
   alive for a 15-minute grace window after completion and the admin notification
   is idempotent (no double e-mail on re-uploads).
 * Fix : admin resend e-mail on Pay4All Shop orders was missing the order link because`
   get_edit_post_link()` returns an empty string when called from the customer’s
   public REST upload (no `edit_post` cap). URL is now built manually.
 * Fix : « Ask to resend » checkboxes now appear on WooCommerce orders even when
   the photos live in the customer’s account bucket rather than the order bucket.
 * UX : the resend mobile page now shows both a QR code AND the clickable URL below
   it so a customer who opened the e-mail on their desktop can either scan or copy-
   paste to their phone. Polls the status endpoint every 4 s so the desktop copy
   flips to « Documents received » once the phone finishes.

#### 1.3.0

 * New **« Ask the customer to resend the photos »** admin action. On any order 
   screen (Pay4All Shop AND WooCommerce – via Pay4All Pro), the age-verification
   lightbox now shows a checkbox next to each photo. The admin ticks the ones to
   retake and clicks the new button – the customer receives an e-mail with a secure
   30-day link that opens the same mobile capture page, this time restricted to 
   the requested photos. New photos overwrite the old encrypted files (same order
   id, so admin decryption keeps working).
 * Once every requested photo has been re-uploaded, the admin gets a single « new
   photos received » notification e-mail – never one per photo.
 * Customer + admin e-mails have their own **subject + body per locale** in `Pay4All
   AGE > Paramètres > Textes > Renvoi`, with placeholders `{customer_firstname}`,`{
   customer_lastname}`, `{order_number}`, `{slots_list}`, `{link}`, `{admin_order_url}`,`{
   site_name}`, `{shop_name}`. Sensible FR / DE / IT / EN defaults ship out of the
   box.

#### 1.2.0

 * New **drag-and-drop reorder** of the ID card and selfies steps from `Pay4All 
   AGE > Paramètres > Documents à demander > Ordre d'affichage`. The chosen order
   applies to both Pay4All Shop and WooCommerce checkouts (single source of truth).
   Keyboard fallback (up/down arrows) included for accessibility.
 * Plugin renamed to « Pay4All Age Verification for WooCommerce & Pay4All Shop »
   to reflect the dual-storefront support already provided when paired with Pay4All
   Pro.
 * Full FR / DE / IT / EN translations for the new « Ordre d’affichage » UI strings.

#### 1.1.2

 * Fix : the KYC text-override form is now correctly styled when embedded inside
   Pay4All Shop’s « Réglages › Vérification d’âge » tab. The settings-page CSS was
   only enqueued on the plugin’s own page, so labels overlapped with inputs and 
   the language accordions rendered as bare `<details>` markup.

#### 1.1.1

 * Renamed the settings page title from « Pay4All — Age verification » to « Pay4All
   Age verification » in the four bundled languages.
 * Added FR/EN/DE/IT translations for the « Important reminder » box on the settings
   page (previously French-only).

#### 1.1.0

 * Fix bug security.

#### 1.0.0

 * Initial release.
 * Product-level _Requires age verification_ checkbox (Pay4All Shop).
 * Cross-device QR flow (desktop QR -> mobile capture page).
 * AES-256-GCM encryption at rest, per-order and per-user derived subkeys.
 * Metabox on the Pay4All Shop order edit screen with nonce-protected decrypted-
   photo streaming and a lightbox to view every document side-by-side.
 * Shield column on the WordPress users list — one click opens the customer’s verified
   documents.
 * Settings page with OR / AND mode, purge delay, per-locale text overrides.
 * FR / DE / IT / EN built-in translations, with 4-language text override per string
   from the settings page.
 * WPML / Polylang aware : translated products inherit the _Requires age verification_
   flag from their source.

## Meta

 *  Versió **1.3.1**
 *  Darrera actualització **fa 1 dia**
 *  Instal·lacions actives **Menys de 10**
 *  Versió del WordPress ** 5.9 o posterior **
 *  Provada fins a **7.0.2**
 *  Versió del PHP ** 7.4 o posterior **
 *  Idioma
 * [English (US)](https://wordpress.org/plugins/pay4all-age-verification/)
 * Etiquetes
 * [adult](https://ca.wordpress.org/plugins/tags/adult/)[age gate](https://ca.wordpress.org/plugins/tags/age-gate/)
   [age verification](https://ca.wordpress.org/plugins/tags/age-verification/)[ID verification](https://ca.wordpress.org/plugins/tags/id-verification/)
   [selfie](https://ca.wordpress.org/plugins/tags/selfie/)
 *  [Vista avançada](https://ca.wordpress.org/plugins/pay4all-age-verification/advanced/)

## Valoracions

Encara no s'ha enviat cap ressenya.

[Your review](https://wordpress.org/support/plugin/pay4all-age-verification/reviews/#new-post)

[Visualitzeu totes les ressenyes](https://wordpress.org/support/plugin/pay4all-age-verification/reviews/)

## Col·laboradors

 *   [ pay4all ](https://profiles.wordpress.org/pay4all/)

## Suport

Teniu quelcom a dir? Necessiteu ajuda?

 [Visualitza els fòrums de suport](https://wordpress.org/support/plugin/pay4all-age-verification/)