Pay4All Shop – Simple order forms with TWINT & STRIPE Payment

Апісанне

Pay4All Shop is a simple and lightweight order form plugin designed for small shops, wineries, caterers, takeaway restaurants, and associations.

It was intentionally created as a simpler alternative to WooCommerce: create an order form, add your products and delivery methods, assign payment methods to each delivery option, and embed the form anywhere on your website using a shortcode.

Available in French, German, Italian, and English.

All customer-facing text can be customized separately in all four supported languages: French, German, Italian, and English.

Main Features

  • Create as many order forms as you need and add your products to each form.
  • Default fields such as first name, last name, email address, phone number, and address are automatically translated into every enabled language.
  • Add, edit, remove, and organize form fields according to your needs. Forms are fully customizable.
  • Products can include an image, regular price, sale price, minimum and maximum quantities, and a short description.
  • Product image size can be configured separately for each form.
  • Multiple product types are supported:

    • Physical products, enabled by default.
    • Virtual products, with a downloadable file delivered after purchase.
    • Event tickets with QR code validation, available with Pay4All Pro.
  • Out-of-stock management: products remain visible, but their quantity selector is disabled.
  • Optional stock management for each product, with email notifications when stock becomes low.
  • Available delivery methods:

    • Local pickup.
    • Flat-rate delivery.
    • Free delivery.
    • Free delivery above a configurable order amount.
    • No delivery required.
  • Payment methods can be assigned individually to each delivery method.
  • Secure delivery of downloadable virtual products.
  • Optional “Remember my information” feature:

    • Customer details are stored only in the customer’s browser.
    • No saved information is sent to the server.
    • Customers can prefill the form with one click during a future visit.
    • Disabling the option immediately removes the saved information.
  • Complete order management:

    • Custom order statuses.
    • Payment statuses.
    • Internal notes.
  • Customizable emails sent to customers and merchants.
  • The email subject, title, introduction, and closing text can be customized separately in each supported language.
  • Export orders in XLS or CSV format, with filters for date, form, and order status.
  • Compatible with the WordPress Privacy API for GDPR data export and erasure requests.
  • Anti-spam protection using a honeypot field, WordPress nonces, and server-side validation.

Included Payment Methods

  • Payment on pickup.
  • Cash on delivery.
  • Bank transfer.
  • Install Pay4All for TWINT to accept TWINT payments.
  • Install Pay4All for Stripe to accept credit and debit card payments.

Age Verification

Install Pay4All Age Verification to add age verification to your products.

Features include:

  • Age verification can be enabled individually for each product with a simple checkbox.
  • Identity document or selfie verification.
  • QR code capture from another device.

Pay4All Pro — Optional

Events and Ticketing

Sell tickets for events, parties, shows, concerts, and other activities.

A unique QR code is generated for every ticket purchased and sent to the customer by email. Tickets can be scanned and validated at the entrance using any smartphone, with no application to install.

The QR ticketing system also includes:

  • A public ticket validation page.
  • A self-service check-in screen.
  • Ticket and participant search.
  • Participant export.

QR ticketing is included with Pay4All Pro, with a free 30-day trial.

Quantity Rules

Define quantity rules by product category or brand:

  • Minimum quantity.
  • Maximum quantity.
  • Quantity multiples.
  • Minimum quantity combined with a required multiple.

Rules are validated both in the customer’s browser and on the server to prevent invalid orders.

Themes and Customization

Quickly customize the appearance of your forms using the Light, Dark, Red, Orange, Yellow, Green, Blue, Purple, and Brown predefined themes, or create a fully customized design using the advanced customization options.

A live preview displays your changes immediately.

Abandoned Carts

Automatically capture incomplete orders and send a follow-up email after a configurable delay.

Each recovery email contains a unique, single-use link that allows the customer to restore the abandoned cart and continue the order where they left off.

Usage Examples

  • Wineries selling products at their cellar door or during events.
  • Cheese shops offering local pickup.
  • Caterers accepting weekly orders.
  • Local shops offering in-store pickup only.
  • Associations accepting online registrations and payments.
  • Businesses selling digital products such as PDF files, MP3 files, online courses, and documents.

Screenshots

Ўсталёўка

  1. Upload the plugin to /wp-content/plugins/pay4all-form/ or install via Plugins › Add New.
  2. Activate the plugin from the Plugins menu.
  3. Open Pay4All Shop in the admin sidebar.
  4. Create your products, delivery methods, then a form.
  5. Copy the form shortcode into any page.

Часта задаваныя пытанні

Do I need WooCommerce?

No. Pay4All Shop is standalone. It does not depend on WooCommerce in any way.

Does it support online payments?

The free version supports manual payments only (pickup, on delivery, bank transfer, TWINT instructions). Automated TWINT payments are available via Pay4All Pro.

Is the plugin GDPR-friendly?

Yes. Customer data is included in WordPress’s Tools › Export / Erase Personal Data workflow.

Will my data be deleted if I uninstall?

No, unless you explicitly enable Réglages › Données › Supprimer les données lors de la désinstallation.

Does the plugin use cookies?

No HTTP cookies are set by the plugin. When the shopper ticks the « Se souvenir de mes informations pour ma prochaine commande » checkbox on the customer step, their contact fields are stored in the browser’s own localStorage (client-side only, never uploaded to the server, one-year retention, scoped per form). Unticking the checkbox and clicking Suivant — or the browser’s Clear site data action — wipes the entry immediately. Nothing is stored when the checkbox stays off.

How do virtual products work?

When you create a product of type Virtual, you upload one file per product. The file is stored in wp-content/uploads/p4all-virtual/, protected by an automatically generated .htaccess (deny from all). After purchase, the customer’s e-mail contains a one-time download link served by the plugin endpoint (?p4all_dl={token}). The link is valid for 60 days.

How does *Out of stock* work?

Tick the Rupture de stock checkbox on a product. The product stays visible in the form so the customer still sees what you usually offer, but the quantity field is greyed and disabled. A red badge labels the product as out of stock. Server-side validation rejects any tampered submission that tries to order an out-of-stock item.

How does *Stock management* work?

Tick Manage stock on a product and enter the quantity available. From that point on:

  • Each order decrements the stock by the quantity ordered (one decrement per ticket / per unit). The decrement happens as soon as the customer validates the order, regardless of the payment status.
  • The order form prevents the customer from ordering more than what is left — the quantity input’s max attribute is capped at the stock available, and a server-side check rejects any tampered submission.
  • When the stock reaches 0, the product is automatically flagged out of stock: it stays visible but cannot be ordered.
  • When an order is deleted from the admin (definitive delete, not just trashed), the stock is restored for every product still in the order. Status changes (paid, cancelled…) do NOT restore stock; only deletion does.
  • If you set a Notify me when stock reaches threshold in Settings › General (under the shop address), an e-mail alert is sent to the notification address as soon as a tracked product crosses the threshold downwards after a sale.
  • A Stock column in the products admin list shows the current quantity (or when stock management is off), highlighted in orange below the threshold and red when out of stock.

Водгукі

На гэты плагін няма водгукаў.

Удзельнікі і распрацоўшчыкі

“Pay4All Shop – Simple order forms with TWINT & STRIPE Payment” is open source software. The following people have contributed to this plugin.

Удзельнікі

Журнал змяненняў

2.5.2

  • The bottom « Publier / Mettre à jour » button on the form editor now shows the correct label depending on the post status (« Publier » while the form is still a draft, « Mettre à jour » once it’s live) — matching WordPress core’s own publish metabox behaviour.
  • Fix : clicking the bottom save button no longer triggers the browser’s « Les modifications que vous avez apportées ne seront peut-être pas enregistrées » warning. The button now delegates to WordPress’s own #publish control, so the full save pipeline (beforeunload cleanup, autosave lock, post-save redirect + notice) runs as expected.

2.5.1

  • Fix : the Age Verification companion plugin is now correctly detected under its current slug (pay4all-age-verification). Previously the stale pay4all-age reference caused the greyed teaser + « Install from WordPress » button to keep showing on the product editor and the Add-ons page even when the plugin was already installed and active.
  • Rename : the Add-ons card labeled « Pay4All Age » is now « Pay4All Age Verification » to match the actual plugin name.

2.5.0

  • New WordPress dashboard widget « Pay4All SHOP ». Adds monthly / yearly / lifetime order counts + revenue, plus a backlog block (new orders to process, orders in preparation, active products, published forms) to the main /wp-admin dashboard. Every tile is clickable and jumps to the matching admin screen. Values reuse the same aggregation as the plugin’s own dashboard so the two views cannot drift.
  • New Shortcode video tutorial. A short MP4 walkthrough is now reachable from three places : the Help page (section 2, step 4), the Forms list (next to Copier in the Shortcode column), and the Shortcode metabox on the form edit screen. Opens in a lightweight in-page modal (native , no external service).
  • New Click-to-copy on the Shortcode metabox input : clicking the field copies the shortcode to the clipboard and flashes a green « Copié ! » badge for confirmation. « Copier » button behaviour on the list is unchanged.
  • Fix : the Comments admin menu no longer shows a stray red « 0 » badge when Pay4All Shop is active. The plugin’s own menu-badge CSS was leaking onto WordPress core’s .awaiting-mod element and overriding the .count-0 { display:none } rule — badges are now scoped to a dedicated .p4all-shop-badge class.
  • Fix : Commentaires site-wide counters now correctly subtract our custom p4all_order_note comment_type (previously the filter existed but did nothing). Cached via the object cache with automatic invalidation on note create / delete / status change.

2.4.0

  • Security — CSV formula injection blocked. Order fields written by anonymous visitors (name, address, comment, product titles) are now prefixed with an apostrophe when they start with =, +, -, @, TAB or CR before being written to the CSV export, so Excel / LibreOffice never evaluate them as formulas (CWE-1236). Real XLSX export was already safe (inline strings) and is unchanged.
  • Security — rate-limit on public form submission. The p4all_form_submit endpoint (formerly unmetered beyond a honeypot + 3s minimum-time trap) is now capped at 5 valid POSTs per minute per IP + form via a transient counter. Blocks scripted mail-bombing of the merchant’s SMTP without breaking the honest UX (filter p4all_form_submit_rate_max to override).
  • Security — anti-spam timestamp is now mandatory. Previously, a missing / zero p4all_ts silently bypassed the minimum-time check ; the field is now required (the same JS that renders the form always sets it) so bots can no longer skip the wait entirely.
  • Security — hardened client IP detection. META_CLIENT_IP now defaults to REMOTE_ADDR and only accepts HTTP_CF_CONNECTING_IP when Cloudflare’s CF-RAY signature is present, preventing trivial WAN-side spoofing that used to let a visitor forge the IP recorded on their order. Non-Cloudflare proxies can be trusted via the new p4all_form_trust_forwarded_for filter.
  • Packaging : leftover languages/pay4all-form-en_US.po.bak removed.

2.3.0

  • New Bank transfer payment method with a per-language description block. The merchant edits the IBAN / BIC / beneficiary in Réglages › Paiement under each language accordion — the input is a multi-line textarea with a fake-data placeholder so an empty field at least shows the expected shape at checkout. The description is rendered with white-space:pre-wrap at checkout (so the IBAN / BIC / beneficiary stay on their own lines) AND injected into the customer confirmation e-mail in the language the customer used to place the order (resolved via the _p4all_lang meta persisted at submission time).
  • Internal : Mailer::payment_instructions() now takes an explicit $lang argument and delegates to Schema::payment_description($method, $lang) for every method — so any future manual method inherits the same per-language override chain (per-lang primary-lang localised default FR default).
  • Translations : « Virement bancaire » label already shipped in the 2.1.0 batch — de : « Banküberweisung », it : « Bonifico bancario », en : « Bank transfer ». The multi-line default templates live in Schema::PAYMENT_DESC_DEFAULTS['bank_transfer'] as per-language constants.

2.2.0

  • New Per-form photo size picker on the form editor (Affichage › Taille). Choose Petite (60 px), Moyenne (120 px), Grande (200 px) or Personnaliser… — the last one reveals a pixel input clamped between 20 and 1000. In List layout the value constrains the photo’s width; in Grid layout its height. Implemented via two CSS custom properties (--p4all-photo-w, --p4all-photo-h) set on the form wrapper, no inline <style> block emitted.
  • Documentation : previously introduced « Remember my information » checkbox on the customer step is now clearly listed under Core features (persisted in localStorage for 1 year, per form, no HTTP cookie).

2.1.0

  • New « Remember my information » opt-in checkbox on the customer step. When ticked, the customer’s contact fields are persisted in the browser’s own localStorage (scoped per form, retention 1 year, no HTTP cookie set) and pre-filled on the next visit. Unticking + clicking Suivant clears the memory. Ships with FR / DE / IT / EN translations.
  • Pay4All Age integration : the « Vérification d’âge » step now auto-skips when the current cart carries no age-restricted product. The customer no longer has to click Suivant on an empty age-check step just because the form’s product catalogue happens to include an adult item they didn’t add to their order. Implemented via a generic data-p4all-skip="1" contract on any .p4all-step, so companion plugins can use the same escape hatch.
  • Checkbox alignment polish : the standalone « Remember me » checkbox uses the same inline-flex layout as the existing checkbox fields (defensive against themes that turn every input into display:block, e.g. Elementor / Astra Ecommerce).

2.0.0

  • Breaking change — five features moved to a separate Pay4All Pro plugin. The free version keeps the form builder, products, deliveries, virtual downloads, orders and e-mails; the following move out:
    • Product filter widget on the public form (categories / brands / sort dropdowns).
    • Categories taxonomy (p4all_product_cat) — including per-language names and per-category quantity rules (min / max / multiple / exact).
    • Brands taxonomy (p4all_product_brand) — same shape as categories.
    • Abandoned cart capture, recovery e-mail and admin page.
    • Ticket product type (QR codes for events) — including the Billets admin page and the public /p4all-ticket/… validation URL.
  • Automatic clean-up on upgrade — activating 2.0.0 once drops the wp_p4all_tickets and wp_p4all_abandoned_carts tables, deletes every term in p4all_product_cat / p4all_product_brand, deletes every ticket post, and un-schedules the hourly p4all_abandoned_cart_tick cron event. Idempotent, guarded by an option so re-installs skip it.
  • XLSX export removed on both the orders CSV screen and the products import/export screen. CSV export is unchanged. XLSX moves to Pro.
  • Product edit screen : the Billet (QR code) option is removed from the product-type dropdown. Existing tickets keep rendering as Physical until edited.
  • Settings › General : Délai d’envoi du mail d’abandon de panier setting removed (no longer used).
  • Help page : reworded to reflect the trimmed feature set.
  • Internal : new Domain\Language helper replaces Domain\Category::current_language() at every call site.

1.4.3

  • New Content picker next to each URL field — a « 🔗 Rechercher » button opens a mini search panel that queries pages, posts, WooCommerce products, every public custom post type, and media attachments (PDFs, images, mp3…). Clicking a result drops the full URL into the input. WPML / Polylang are detected automatically: on the DE tab the search only returns DE pages, on IT only IT, etc. Media stays language-agnostic (a PDF is the same file in every locale). AJAX endpoint requires edit_posts + a nonce.
  • Full DE / IT / EN translations for the eleven new admin strings introduced by the « Learn more » link, the picker, and the photo lightbox (labels, placeholders, help text, status messages).
  • Plugin Check compliance polishphpcs:disable / phpcs:enable block around the $_FILES sanitisation in MetaBoxes::store_virtual_upload() (nonce is verified upstream in save()); documented ignores for WPML’s public wpml_switch_language hook (must be invoked verbatim to trigger their language switcher) and for the intentional suppress_filters on the media query used by the picker (language-agnostic search is the product decision).

1.4.2

  • New « Learn more » link per product — two new fields (URL + link label) on each language tab of the product edit screen. When the URL is set, a link is rendered under the short description in the order form and opens in a new tab. The Link label field is pre-filled with a language-specific default on every tab (FR « Découvrez en plus… », DE « Erfahren Sie mehr… », IT « Scopri di più… », EN « Learn more… ») regardless of the admin’s own locale; the merchant is free to overwrite any of them. Same default kicks in on the front-end so a visitor in DE (or IT / EN) always sees the label in their language, even when the merchant left the field blank. URLs are validated at save with esc_url_raw() (http / https / mailto / tel only, javascript: rejected).
  • New Product photo lightbox — clicking the product thumbnail on the first step of the form now opens the full-size photo in an overlay. Keyboard-accessible (Enter / Space to open, ESC to close), non-destructive to the form (body scroll is temporarily locked). No dependency added; pure vanilla JS.
  • Security hardening — three fixes triggered by an internal security review:
    • Path traversal fix in the virtual-download endpoint (?p4all_dl=). The customer-facing streamer now rejects any filename containing directory separators, .., or NULL bytes, and enforces a realpath() boundary check that guarantees the resolved path lives inside the private uploads folder. Protects against manipulated _p4all_virtual_downloads meta on stores with a compromised admin account or a SQL injection introduced by a third-party plugin.
    • X-Frame-Options / CSP frame-ancestors now emitted on every front-end page rendering the [pay4all_form] shortcode. Default: SAMEORIGIN — blocks brand impersonation via cross-origin iframes and closes the per-domain-licence bypass some agencies used by iframing a licensed shop on many client sites. Configurable via a new Réglages › Général option (sameorigin / deny / off).
    • Virtual-product upload allowlist — merchant-configurable list of accepted file extensions (default: pdf, mp3, mp4, m4a, epub, zip, jpg, jpeg, png, gif, svg, doc(x), xls(x), ppt(x), txt, csv, html). Blocks executable uploads (.php, .phtml, .exe, .htaccess…) BEFORE wp_handle_upload() runs. Set the option to an empty value to restore the legacy behaviour of allowing anything. The private uploads folder is now also guarded by a web.config deny rule for IIS hosts, in addition to the existing .htaccess.
  • Admin menu badge polish — the “Commandes” count badge next to Pay4All SHOP now uses the same red (#d63638) and compact sizing as WordPress core’s update available pill, and stays visible on every admin screen (previously the CSS only loaded on Pay4All Form pages, so the badge disappeared on the Dashboard).
  • Admin menu i18n — sub-entries Paramètres and Licences under Pay4All AGE, plus the WooCommerce entry-point label, are now localised in DE / IT / EN based on the admin locale.
  • KYC tab visual polish — the accordion widget on Réglages › Protection des mineurs now matches the visual language of the Paiements tab (rounded card, chevron, language pill), and the accordions honour the languages selected in Réglages › Langue (so a DE-only shop only shows the DE accordion here).
  • Plugin Check clean-up — nonce comments, sanitize_text_field( wp_unslash() ) on remaining $_POST reads, esc_url() on the licence page form action, wp_delete_file() in the KYC storage purge, and Plugin Check ignore blocks documented for WPML hooks (wpml_element_trid, wpml_get_element_translations) that intentionally do not carry the plugin prefix.

1.4.1

  • New Client-side product filtering — an optional filter bar can be enabled per form (Form editor › Affichage des produitsAfficher les filtres). Customers can narrow the product list on the first step by category, brand and sub-taxonomies, with an optional item-count next to each option. Fully client-side, no page reload.
  • Multilingual category / brand labels — every category and brand can carry a customer-facing name in each activated language, plus a « Tous les… » label for filter dropdowns. Empty fields fall back to the WordPress canonical term name. Drag-and-drop reorder from the taxonomy list.
  • Minimum order amount is now per-form — the Montant minimum de commande panel has moved from Réglages › Commandes to each form’s edit screen (right above Affichage des produits), so different forms can have different thresholds. Includes the per-language error message (with %s for the amount) and live validation on the product step: the Suivant button is blocked and a red alert appears as soon as the subtotal drops below the floor. Existing global setting is honoured as fallback for forms that haven’t set their own.
  • Compatibility with Pay4All Age plugin improved.

1.4.0

  • New Compatible with Pay4All AGE Protection of minors (age verification) — enable per product with the Requires age verification checkbox on the product edit screen. At checkout the customer scans a QR code, opens a mobile page and captures their ID (recto + verso) and a selfie; the order cannot be validated until every required slot is present.
  • Cross-device flow — the QR code embeds a short-lived session token (20 min); the desktop cart polls the server and unlocks automatically as soon as the mobile capture is complete, without asking the customer to reload.
  • Encryption at rest — every photo is encrypted with AES-256-GCM using a per-order subkey derived via HMAC-SHA256 from a master key stored in wp-content/uploads/p4all-secure/kyc.key (outside the database backup). Ciphertexts live in a private folder guarded by .htaccess + index.php + web.config.
  • Admin-only decrypted view — a Protection des mineurs section on the order page streams the decrypted photos through a nonce-protected admin endpoint (never served publicly, never written back to disk).
  • Yellow warning banner in the admin new-order e-mail when the order requires age verification, with a Voir la commande button that links straight to the order edit screen.
  • Auto-purge — deleting an order also deletes its KYC directory. A daily cron purges session buckets older than 24 h.
  • All KYC-related strings translated in FR / DE / IT / EN.

1.3.1

  • New Timezone setting in Settings › General — surfaces the WordPress global timezone selector for admins who don’t know where to find it. Defaults to Europe/Paris when not configured. Modifying it updates the standard WP timezone_string option.
  • Dates in Pay4All Shop › Abandon panier admin page now use get_date_from_gmt() for accurate conversion of UTC-stored timestamps to the site’s configured timezone.
  • Renamed menu label from Abandon de panier to Abandon panier for compactness; sub-menu translated in all four languages.
  • Plugin Check / WP.org compliance: escaped $cart_id output in the abandoned-cart view dialog, and added WordPress.DB.PreparedSQL.InterpolatedNotPrepared + PluginCheck.Security.DirectDB.UnescapedDBParameter ignores on the wp_p4all_abandoned_carts custom-table queries (table name built from $wpdb->prefix + literal suffix).

1.3.0

  • New Abandoned cart capture and recovery — when a customer fills the contact-info step (with their e-mail) and clicks Next but never validates, the cart is stored. A recovery e-mail with a one-time link is automatically sent after a configurable delay (default 10 days). Clicking the link returns the customer to the form with all their items, contact fields, delivery and payment method already pre-filled.
  • New admin page Pay4All Shop › Abandon panier (above Billets) — lists every captured cart with filters (pending / e-mail sent / recovered / converted), totals, dates and a delete action.
  • New setting Réglages › Général › Délai d’envoi du mail d’abandon de panier (jours) — 0 disables, default 10. Carts older than 90 days are automatically purged (GDPR).
  • New e-mail template Abandoned cart recovery in Réglages › E-mails, editable per language (subject / heading / intro / outro), with {site_name}, {customer_firstname}, {customer_email} and {recover_url} placeholders.
  • GDPR exporter and eraser hooks include abandoned-cart rows in WordPress’s Tools › Export / Erase Personal Data.
  • Hourly cron p4all_abandoned_cart_tick sends due recovery e-mails and purges old rows.

1.2.0

  • New Hide a product checkbox on the product edit screen — the product is omitted from the form entirely (no badge, no greyed-out field). Server-side rejects any tampered order containing a hidden product. Useful for archiving seasonal items without deleting them.
  • Stock-related checkboxes reordered for clarity: Hide this product Out of stock Manage stock (+ quantity field).
  • New Stock management (optional, per product) — tick Manage stock on a product to track its quantity. Stock is decremented at every order (one unit per ticket / per item), the customer cannot order more than what is left, and the product is automatically flagged out of stock when the stock hits 0.
  • Stock restored on order deletion — deleting an order definitively (from trash or via the delete button) restores the stock of every product still present in that order. Status changes (paid, cancelled, etc.) do not restore stock; only deletion does.
  • Low-stock e-mail alert — set Settings › General › Notify me when stock reaches (under the shop address) to a non-zero threshold; an alert is e-mailed to the notification address each time a tracked product crosses the threshold downwards after a sale.
  • New Stock column in the products admin list — shows when stock management is off, the current quantity otherwise (orange if at or below threshold, red 0 Out of stock when empty).

1.1.0

  • New product type Virtual — upload one downloadable file per product, customer receives a one-time link valid 60 days, served by the plugin’s protected endpoint (files stored in a private folder with deny-all .htaccess).
  • New product type Ticket — one QR code per seat ordered, sent in the order email, scannable from any smartphone, with a public validation page showing green (available) or red (already used).
  • New admin page Pay4All Shop › Billets — list every QR ticket, search by first/last name / city / e-mail, validate manually, export to CSV.
  • Out of stock flag on every product — product stays visible, quantity field is greyed and disabled, server-side rejects tampered orders.
  • Default form fields (first name, last name, e-mail, phone, address, etc.) are now pre-translated in every activated language at form creation time.
  • Per-delivery payment methods — accepted payment methods are now configured per delivery method (a delivery edit screen has a Modes de paiement acceptés section), so each delivery can show its own payment choices to the customer. Forms without any delivery still use the legacy per-form payment picker.

1.0.0

  • Initial release.