外掛說明
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). Install it alongside Pay4All Shop and it will only surface where a form contains an age-restricted product.
WooCommerce support
For WooCommerce stores that want the complete verification flow : including a QR-code checkout panel and a product-level checkbox — the WooCommerce integration is available in the paid Pay4All Pro add-on, distributed through pay4all.ch and not through WordPress.org.
How it works
- Merchant ticks Requires age verification on any product edit screen (Pay4All Shop product).
- When a customer adds such a product to their form, a panel appears in the KYC step showing a QR code.
- Customer scans the QR with their phone -> the mobile capture page opens -> they take the required photos with their phone camera.
- The desktop form polls the server every 4 seconds and unlocks automatically when every required slot is filled — no page refresh needed.
- 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_userscapability. - 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.
螢幕擷圖





安裝方式
- Upload the plugin to
/wp-content/plugins/pay4all-age-verification/or install via Plugins > Add New. - Activate it from the Plugins menu.
- Open Pay4All AGE > Paramètres to tune what documents you require and to override the customer-facing texts if needed.
- On each product that requires an age check, tick the Requires age verification checkbox on the product edit screen (Pay4All Shop product).
常見問題集
-
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.phpandweb.configso 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 encryptswp-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_orderhook) and Pay4All Shop order deletion triggerKycStorage::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_userhook firesKycStorage::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
.pofile. -
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.
使用者評論
這個外掛目前沒有任何使用者評論。
參與者及開發者
變更記錄
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.
