{"id":388654,"date":"2026-10-19T13:50:22","date_gmt":"2026-10-19T13:50:22","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/wpcoretools-email-verify\/"},"modified":"2026-10-25T13:29:35","modified_gmt":"2026-10-25T13:29:35","slug":"wpcoretools-email-verify","status":"publish","type":"plugin","link":"https:\/\/tr.wordpress.org\/plugins\/wpcoretools-email-verify\/","author":23437078,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.0.8","stable_tag":"1.0.8","tested":"7.1.4","requires":"6.4","requires_php":"7.4","requires_plugins":null,"header_name":"WPCoreTools Email Verify","header_author":"WPCoreTools","header_description":"Simple email verification. Customers click a link in their email before they can log in or place a WooCommerce order. No OTP, no popup, no third-party API.","assets_banners_color":"485f82","last_updated":"2026-10-25 13:29:35","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"","header_author_uri":"https:\/\/wpcoretools.com\/","rating":0,"author_block_rating":0,"active_installs":0,"downloads":177,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.0.7":{"tag":"1.0.7","author":"wpcoretools","date":"2026-10-19 13:52:25","revision":3754878},"1.0.8":{"tag":"1.0.8","author":"wpcoretools","date":"2026-10-25 13:29:35","revision":3764660}},"upgrade_notice":[],"ratings":[],"assets_icons":{"icon-128x128.gif":{"filename":"icon-128x128.gif","revision":3756548,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.gif":{"filename":"icon-256x256.gif","revision":3756548,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3754871,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3754871,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.0.7","1.0.8"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3754871,"resolution":"1","location":"assets","locale":"","width":1280,"height":1000},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3754897,"resolution":"2","location":"assets","locale":"","width":1280,"height":800},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3754871,"resolution":"3","location":"assets","locale":"","width":1280,"height":800},"screenshot-4.png":{"filename":"screenshot-4.png","revision":3754871,"resolution":"4","location":"assets","locale":"","width":1280,"height":800},"screenshot-5.png":{"filename":"screenshot-5.png","revision":3754871,"resolution":"5","location":"assets","locale":"","width":1280,"height":800},"screenshot-6.png":{"filename":"screenshot-6.png","revision":3754871,"resolution":"6","location":"assets","locale":"","width":1280,"height":800}},"screenshots":{"1":"The setup wizard: ready-made setups (Shop, Strict, Community, Custom), each listing what it does for customers.","2":"The settings page.","3":"The notice an unconfirmed customer sees on My Account, with the resend link and the \"Wrong address?\" form.","4":"Checkout for an unconfirmed customer: why ordering waits, with a resend link.","5":"The Users list with the Verified column, the status filter and bulk actions.","6":"The dashboard widget with verified and pending counts."}},"plugin_section":[262246],"plugin_tags":[287524,2656,3148,18971,286],"plugin_category":[45],"plugin_contributors":[254220],"plugin_business_model":[],"class_list":["post-388654","plugin","type-plugin","status-publish","hentry","plugin_section-dashboard-widgets","plugin_tags-account-confirmation","plugin_tags-anti-spam","plugin_tags-checkout","plugin_tags-email-verification","plugin_tags-woocommerce","plugin_category-ecommerce","plugin_contributors-wpcoretools","plugin_committers-wpcoretools"],"banners":{"banner":"https:\/\/ps.w.org\/wpcoretools-email-verify\/assets\/banner-772x250.png?rev=3754871","banner_2x":"https:\/\/ps.w.org\/wpcoretools-email-verify\/assets\/banner-1544x500.png?rev=3754871","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/wpcoretools-email-verify\/assets\/icon-128x128.gif?rev=3756548","icon_2x":"https:\/\/ps.w.org\/wpcoretools-email-verify\/assets\/icon-256x256.gif?rev=3756548","generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/wpcoretools-email-verify\/assets\/screenshot-1.png?rev=3754871","caption":"The setup wizard: ready-made setups (Shop, Strict, Community, Custom), each listing what it does for customers."},{"src":"https:\/\/ps.w.org\/wpcoretools-email-verify\/assets\/screenshot-2.png?rev=3754897","caption":"The settings page."},{"src":"https:\/\/ps.w.org\/wpcoretools-email-verify\/assets\/screenshot-3.png?rev=3754871","caption":"The notice an unconfirmed customer sees on My Account, with the resend link and the \"Wrong address?\" form."},{"src":"https:\/\/ps.w.org\/wpcoretools-email-verify\/assets\/screenshot-4.png?rev=3754871","caption":"Checkout for an unconfirmed customer: why ordering waits, with a resend link."},{"src":"https:\/\/ps.w.org\/wpcoretools-email-verify\/assets\/screenshot-5.png?rev=3754871","caption":"The Users list with the Verified column, the status filter and bulk actions."},{"src":"https:\/\/ps.w.org\/wpcoretools-email-verify\/assets\/screenshot-6.png?rev=3754871","caption":"The dashboard widget with verified and pending counts."}],"raw_content":"<!--section=description-->\n<p><strong>WPCoreTools Email Verify<\/strong> asks new customers to confirm their email address before they can order. They get an email with a link, they click it, and they are confirmed. There are no codes to type, no popups and no outside service.<\/p>\n\n<p>You decide what an unconfirmed customer has to wait for. The recommended \"Shop\" setup lets them log in and browse straight away and holds back only ordering. The setup wizard also offers stricter and looser setups, each explained in plain words.<\/p>\n\n<p>People who registered before you activated the plugin are never asked. Only new sign-ups confirm, and guest checkout is not affected.<\/p>\n\n<p>The plugin is completely free. There is no Pro version, no paid add-on, no license key, no advertising and no tracking.<\/p>\n\n<h4>Features<\/h4>\n\n<ul>\n<li><strong>Confirmation link by email.<\/strong> Links are valid for 7 days by default (1 to 90). Tokens are stored hashed.<\/li>\n<li><strong>Choose what waits for confirmation:<\/strong> placing orders, logging in, comments and reviews, creating an account at checkout, wp-admin, changing the email address in the profile, and selected capabilities.<\/li>\n<li><strong>Setup wizard<\/strong> with ready-made setups: Shop (recommended), Strict, Community or Custom. You can run it again at any time.<\/li>\n<li><strong>Clear notices for customers<\/strong> on My Account, the cart and checkout, with a resend link that counts down until a new email can be sent.<\/li>\n<li><strong>Wrong address? Change it.<\/strong> A customer who mistyped their address can correct it from the notice and get a new link.<\/li>\n<li><strong>Resend form for logged-out visitors<\/strong> on the login page. It is rate-limited and never reveals whether an address is registered.<\/li>\n<li><strong>Safe against link scanners.<\/strong> Mail programs that open links in advance cannot confirm an account. Anyone not logged in as that customer sees a \"Confirm my email\" button first.<\/li>\n<li><strong>WooCommerce support:<\/strong> classic checkout, the Cart and Checkout blocks, Pay for order links and HPOS. With WooCommerce 11, its own email confirmation and this plugin stay in step, so customers see one prompt.<\/li>\n<li><strong>Admin tools:<\/strong> a Verified column, filter and bulk actions on the Users list, a Verified column on the Orders list, a dashboard widget, Site Health checks, CSV exports and a log of emails that could not be sent.<\/li>\n<li><strong>Warns about a second verification plugin<\/strong>, which would leave customers confirmed in one and still blocked by the other.<\/li>\n<li><strong>Plain-text email by default<\/strong>, or WooCommerce's email template, editable under WooCommerce &gt; Settings &gt; Emails.<\/li>\n<li>Works without WooCommerce, and on Multisite.<\/li>\n<\/ul>\n\n<h4>For developers (optional)<\/h4>\n\n<p>Everything above works out of the box, with no code. The hooks below are only for developers who want to extend the plugin, for example to send confirmed customers to a page of their own, reword a notice, or tell another system about a confirmation. Each hook is explained with a copy-and-paste example on the <a href=\"https:\/\/wpcoretools.com\/plugins\/wpcoretools-email-verify-hooks\">hooks page for developers<\/a>.<\/p>\n\n<p>Filters: <code>wpcev_is_blocked( $blocked, $user_id )<\/code> (the final word on whether a user is held back), <code>wpcev_is_verified( $verified, $user_id )<\/code> (ask from your own code whether a user is confirmed), <code>wpcev_skip_verification_on_register( $skip, $user_id )<\/code> (do not ask a new account, for example from single sign-on), <code>wpcev_expiry_days( $days, $user_id )<\/code> (how long a link stays valid, 1 to 90 days), <code>wpcev_verification_url( $url, $user_id, $token )<\/code> (the link in the email), <code>wpcev_verification_email( $args, $token )<\/code> (subject, body, headers and recipient of the plain-text email), <code>wpcev_notice_message( $html, $context, $user_id )<\/code> (the wording of the main notices: My Account, cart and checkout, Pay for order, the sign-up notice, the login error and the banners), <code>wpcev_show_notice( $show, $location, $user_id )<\/code> (hide a notice on some pages), <code>wpcev_verify_redirect_url( $url, $user_id, $result, $viewer )<\/code> (the page shown after the link worked), <code>wpcev_verify_landing( $landing, $result )<\/code> (title and body of the result page on sites without WooCommerce), <code>wpcev_new_email_errors( $errors, $email, $user_id )<\/code> (refuse a new address in the \"Wrong address?\" form), <code>wpcev_verify_on_password_reset( $verify, $user_id )<\/code>, <code>wpcev_run_wc_account_email_checks( $run )<\/code>, <code>wpcev_sync_to_woocommerce( $sync, $user_id, $reason, $direction )<\/code>, <code>wpcev_verified_via_label( $label, $via, $user_id )<\/code>, <code>wpcev_should_purge_user( $delete, $user_id )<\/code> and <code>wpcev_purge_reassign_to( $reassign, $user_id )<\/code> (the auto-delete of abandoned sign-ups).<\/p>\n\n<p>Actions: <code>wpcev_verification_sent( $user_id )<\/code> and <code>wpcev_verification_send_failed( $user_id, $code )<\/code> (an email went out, or could not be sent), <code>wpcev_email_confirmed( $user_id, $source )<\/code> (the customer proved the inbox), <code>wpcev_user_verified( $user_id, $reason )<\/code> and <code>wpcev_user_unverified( $user_id, $reason )<\/code> (the status changed, for any reason), <code>wpcev_verify_link_failed( $user_id, $problem )<\/code> (an expired or invalid link was used) and <code>wpcev_before_purge_user( $user_id, $reassign )<\/code> (the auto-delete is about to remove an account).<\/p>\n\n<h4>Privacy<\/h4>\n\n<p>The plugin contacts no outside service and collects no usage data. It supports WordPress's personal data export and erase tools. The resend form's rate limit stores only a hash of the visitor's IP address, for one hour.<\/p>\n\n<h4>Requirements<\/h4>\n\n<p>WordPress 6.4 or later and PHP 7.4 or later. WooCommerce is optional. If you use it, WooCommerce 9.2 or later is required, which itself needs WordPress 6.5.<\/p>\n\n<h4>External services<\/h4>\n\n<p>This plugin does not use any external services.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>In wp-admin go to Plugins &gt; Add New Plugin, search for \"WPCoreTools Email Verify\", then install and activate it. You can also upload the plugin folder to <code>wp-content\/plugins\/<\/code>.<\/li>\n<li>The setup wizard opens after activation. Pick a setup, or skip it and keep the defaults.<\/li>\n<li>Change anything later under Settings &gt; Email Verify, where you can also start the wizard again.<\/li>\n<li>From then on, new registrations are asked to confirm their email address.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"will%20this%20lock%20out%20my%20existing%20customers%3F\"><h3>Will this lock out my existing customers?<\/h3><\/dt>\n<dd><p>No. Only accounts created after activation are asked to confirm. Existing accounts are treated as confirmed.<\/p><\/dd>\n<dt id=\"does%20it%20affect%20guest%20checkout%3F\"><h3>Does it affect guest checkout?<\/h3><\/dt>\n<dd><p>No. Every restriction applies only to logged-in customers, so guests check out and comment as before.<\/p><\/dd>\n<dt id=\"does%20it%20work%20with%20the%20cart%20and%20checkout%20blocks%3F\"><h3>Does it work with the Cart and Checkout blocks?<\/h3><\/dt>\n<dd><p>Yes. It covers the blocks, the classic checkout and Pay for order links. Unconfirmed customers see why they cannot order yet, with a resend link.<\/p><\/dd>\n<dt id=\"can%20a%20new%20customer%20create%20an%20account%20at%20checkout%20and%20order%20right%20away%3F\"><h3>Can a new customer create an account at checkout and order right away?<\/h3><\/dt>\n<dd><p>By default, yes: the account is created while that first order is placed, so there is nothing to confirm yet. After that the customer must confirm before ordering again. To make the first order wait as well, turn on \"Block signup at checkout\" in Settings &gt; Email Verify.<\/p><\/dd>\n<dt id=\"a%20customer%20did%20not%20get%20the%20email.%20what%20now%3F\"><h3>A customer did not get the email. What now?<\/h3><\/dt>\n<dd><p>They can use the resend link in the notice, or the \"Resend verification email\" link on the login page, which also works while logged out. Admins can resend from the Users list or the user's profile. If no emails arrive at all, check the \"Failed sends\" tab and the Site Health screen.<\/p><\/dd>\n<dt id=\"woocommerce%2011%20has%20its%20own%20email%20confirmation.%20will%20customers%20see%20two%20prompts%3F\"><h3>WooCommerce 11 has its own email confirmation. Will customers see two prompts?<\/h3><\/dt>\n<dd><p>No. While this plugin is enabled it hides WooCommerce's prompt (WooCommerce 11.1 and later). Confirming in either place counts in both, and marking a customer verified or unverified as an admin is passed on to WooCommerce. Existing customers can be synced once from the Tools tab, in the background and without sending any email.<\/p><\/dd>\n<dt id=\"what%20happens%20when%20a%20customer%20changes%20their%20email%20address%3F\"><h3>What happens when a customer changes their email address?<\/h3><\/dt>\n<dd><p>The new address has to be confirmed. The customer gets a link at the new address and waits for confirmation again. Staff in the exempt roles keep their status. You can also refuse email changes until the first address is confirmed.<\/p><\/dd>\n<dt id=\"can%20admins%20confirm%20or%20unconfirm%20a%20user%20by%20hand%3F\"><h3>Can admins confirm or unconfirm a user by hand?<\/h3><\/dt>\n<dd><p>Yes, on the Users list (row and bulk actions), on the user's profile, and with WP-CLI: <code>wp wpcev status|verify|unverify|resend &lt;user&gt;<\/code>.<\/p><\/dd>\n<dt id=\"does%20it%20block%20disposable%20email%20addresses%3F\"><h3>Does it block disposable email addresses?<\/h3><\/dt>\n<dd><p>No. That is the job of our separate free plugin, WPCoreTools Disposable Email Guard. The two work together.<\/p><\/dd>\n<dt id=\"why%20does%20it%20look%20at%20other%20plugins%27%20code%3F\"><h3>Why does it look at other plugins' code?<\/h3><\/dt>\n<dd><p>To warn you about a second email verification plugin. It reads the code that other plugins hook into registration, login and checkout, and, only when an admin presses \"Scan the code now\", the code of active plugins, mu-plugins and the theme. Everything stays on your server: nothing is sent anywhere and nothing is changed.<\/p><\/dd>\n<dt id=\"does%20it%20work%20on%20multisite%3F\"><h3>Does it work on Multisite?<\/h3><\/dt>\n<dd><p>Yes, including network activation. People who sign up through WordPress's multisite activation link are not asked to confirm a second time.<\/p><\/dd>\n<dt id=\"can%20i%20show%20my%20own%20page%20after%20a%20customer%20confirms%3F\"><h3>Can I show my own page after a customer confirms?<\/h3><\/dt>\n<dd><p>Yes. Enter the page under Settings &gt; Email Verify &gt; Settings, \"After confirming, send the customer to\" (the setup wizard asks for it too). It must be a page on your site. Clicking the link does not log the customer in, so the page should offer a login link. Expired or invalid links still show the built-in pages, because those carry the resend link. Developers can set or change the page with the <code>wpcev_verify_redirect_url<\/code> filter.<\/p><\/dd>\n<dt id=\"are%20there%20hooks%20for%20developers%3F\"><h3>Are there hooks for developers?<\/h3><\/dt>\n<dd><p>Yes, but you do not need them: the plugin is complete without any code. For developers who want to extend it there are 17 filters and 7 actions, listed under \"For developers\" above and explained with examples on the <a href=\"https:\/\/wpcoretools.com\/plugins\/wpcoretools-email-verify-hooks\">hooks page for developers<\/a>.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.0.8<\/h4>\n\n<ul>\n<li>New setting \"After confirming, send the customer to\" (Settings tab and the wizard's email step): a page of your own, for example a \"Thank you, your email is confirmed\" page, shown after the verification link worked. Blank keeps the default (My Account with a notice, or the plugin's plain confirmation page without WooCommerce). Only pages on this site are accepted. Expired or invalid links keep the built-in pages, which carry the resend link.<\/li>\n<li>New filter for developers, <code>wpcev_verify_redirect_url( $url, $user_id, $result, $viewer )<\/code>, to set that page in code. <code>$user_id<\/code> is 0 when the request does not prove who holds the link (a repeated click from a browser that is not logged in as that account).<\/li>\n<li>New hooks for developers (optional; the plugin needs none of them): the actions <code>wpcev_verification_sent<\/code>, <code>wpcev_verification_send_failed<\/code>, <code>wpcev_verify_link_failed<\/code> and <code>wpcev_before_purge_user<\/code>, and the filters <code>wpcev_notice_message<\/code> (reword the main notices a customer reads), <code>wpcev_show_notice<\/code> (hide a notice on some pages), <code>wpcev_verify_landing<\/code> (the result page on sites without WooCommerce) and <code>wpcev_expiry_days<\/code> (link lifetime per user). Every hook is documented on the <a href=\"https:\/\/wpcoretools.com\/plugins\/wpcoretools-email-verify-hooks\">hooks page for developers<\/a>.<\/li>\n<li>Site Health's plugin section lists the page.<\/li>\n<li>Fixed: the auto-delete of abandoned sign-ups was meant to skip accounts that own any post, page or media, but that check never matched, so such an account could be deleted with its content. It now skips them as documented.<\/li>\n<\/ul>\n\n<h4>1.0.7<\/h4>\n\n<ul>\n<li>First public release.<\/li>\n<\/ul>\n\n<p>The full development history is in changelog.txt in the plugin folder.<\/p>","raw_excerpt":"Simple email verification for WordPress and WooCommerce. Click-a-link confirmation \u2014 no OTP, no popup, no third-party API.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/tr.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/388654","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tr.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/tr.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/tr.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=388654"}],"author":[{"embeddable":true,"href":"https:\/\/tr.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/wpcoretools"}],"wp:attachment":[{"href":"https:\/\/tr.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=388654"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/tr.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=388654"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/tr.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=388654"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/tr.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=388654"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/tr.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=388654"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/tr.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=388654"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}