WooCommerce B2B registration with manual approval: a plugin you can build today
· 5 min read
WooCommerce's default account system treats every registered customer the same. There is a single customer role, prices display identically to all of them, and nothing in the checkout flow distinguishes a retail buyer from a trade account. Adding a wholesale tier means solving three things at once: a separate registration path for businesses, a way to hold new applications for review before the discount activates, and price display logic that only shows reduced prices to accounts you have approved.
Several paid plugins tackle the full B2B problem set. WholesaleX, B2B King and similar extensions handle per-product custom prices, quantity-break tiers, minimum order requirements, net payment terms and a separate catalogue visible only to trade accounts. For a shop adding a wholesale tier for the first time, where pricing is a flat percentage off retail and applications need a human decision before they go live, that feature set is significant overhead.
The plugin described here covers the core of the workflow: a front-end application form, a pending role that holds new accounts, an admin email with approve and decline links, and a configurable percentage discount on WooCommerce prices. It does not try to compete with the full-featured extensions on catalogue management or per-product pricing.
What one build gives you
- Front-end trade account application form via a [wholesale_registration] shortcode
- wholesale_pending role holding applications until manually reviewed
- Admin email notification with nonce-signed one-click approve and decline links
- Automatic role change to wholesale_customer and confirmation email on approval
- Site-wide percentage discount applied to WooCommerce prices for approved accounts
What it does not do
- Per-product or per-category wholesale prices - only a single site-wide percentage
- Quantity-based pricing tiers or minimum order requirements
- A separate wholesale product catalogue hidden from retail visitors
- Net payment terms or purchase-order payment methods
- A self-service account portal for wholesale customers to manage their own details
B2B King does these. This covers the part most sites use.
The prompt
Loads into the composer so you can edit it first. Nothing is built, and nothing is charged, until you send it.
Build a WooCommerce plugin that adds wholesale registration with manual approval. Register two custom WordPress user roles: wholesale_pending and wholesale_customer. Add a [wholesale_registration] shortcode that renders a front-end form with fields for company name, contact name, email, phone and a business description textarea. On valid form submission: if no WordPress user exists for that email, create one with the username derived from the email, assign the wholesale_pending role, store company name and business description in user meta with keys _wholesale_company and _wholesale_description, and send an email to get_option('admin_email') containing the applicant's details and two admin URLs constructed with add_query_arg and wp_nonce_url pointing to admin.php with a custom action parameter (wholesale_approve or wholesale_decline) and the user ID; then display a success message on the page. If an account already exists for that email, display an error message. Handle both admin actions in admin_init: verify the nonce, then for wholesale_approve change the user role to wholesale_customer using WP_User::set_role and send a welcome email to the user; for wholesale_decline delete the user with wp_delete_user and send a short rejection email to the applicant. Add a submenu page under the WooCommerce admin menu called Wholesale with a single settings field for wholesale_discount_percent using the Settings API, defaulting to 10. Hook into woocommerce_product_get_price and woocommerce_product_get_regular_price with priority 99 to multiply the price by (1 - discount/100) when the current user has the wholesale_customer role. Filter woocommerce_get_price_html to append a span with class wholesale-price-label and text Wholesale price for wholesale_customer users. Register all hooks inside a function attached to plugins_loaded.
Why WooCommerce's default roles do not handle this
WordPress ships with a customer role and a subscriber role. WooCommerce adds nothing that maps to the concept of a pending trade applicant. Without a plugin, the typical workaround is a contact form, an inbox, a manual check of who the applicant is, and then a hands-on edit of their user profile to switch their role to something the store treats differently. That process does not scale past a handful of accounts and breaks the moment the person doing the approvals is unavailable.
WooCommerce prices are also public by default. You can hide a product, but there is no built-in way to show one price to retail customers and a different price to logged-in wholesale accounts. The role-based pricing that makes a B2B tier work is always a plugin problem.
The gap this plugin fills is the approval loop: a business applies, the admin decides, the role changes, the discount activates. Everything else in the shop continues working as it did.
What the plugin does
You place a [wholesale_registration] shortcode on a dedicated page. The form has fields for company name, contact name, email address, phone number and a short business description. On submission, the plugin creates a WordPress user account with a wholesale_pending role and stores the company name and description in user meta.
The site admin receives an email with the applicant's details and two links: one to approve and one to decline. Both links are signed with a nonce and handled by a custom admin action. Clicking approve switches the user's role to wholesale_customer and sends them a welcome email. Clicking decline deletes the account and sends a short rejection email to the applicant.
A settings page under WooCommerce in the admin menu has a single field for the wholesale discount percentage. WooCommerce's pricing hooks read this value whenever a logged-in wholesale_customer views a price. The discounted figure appears on the shop page, the product page and the cart. A 'Wholesale price' label is appended so the customer can see the rate is applied.
Who this is for
WooCommerce stores adding a wholesale or trade tier for the first time, where pricing is a flat discount rather than a per-product matrix. The plugin suits a shop with twenty or thirty wholesale accounts that wants a structured application process instead of managing approvals through email.
Store owners who want to keep retail customers and wholesale customers in the same catalogue. Because the plugin discounts from the existing retail price, you maintain one set of products and let the role determine what each customer pays.
Developers inheriting a store that has been handling trade applications by hand and want to give the admin a proper approve-and-reject flow without introducing a heavyweight B2B extension.
Who should use a paid extension instead
If you need different prices on individual products rather than a site-wide percentage, a proper B2B extension is the right tool. WholesaleX and B2B King both support product-level and category-level wholesale prices, which a single discount percentage cannot express.
Quantity-break pricing, minimum order values and net payment terms are all out of scope here. If your trade accounts need to order a minimum quantity before the discount applies, or pay on account at the end of the month, an extension that models those rules is the honest answer.
If you have a wholesale catalogue that you want hidden from retail visitors, the plugin below does not support that. It works on the assumption that retail and wholesale share the same catalogue and the only difference is price.
For stores where wholesale is the primary business rather than a secondary channel, invest in a maintained extension. The plugin here is the right scope for a shop adding its first trade tier and wanting human review on every application.
How to build it
Paste the prompt below into Steem. The plugin installs under Plugins > Add New > Upload Plugin. Once active, create a new page and add the [wholesale_registration] shortcode. Visit WooCommerce > Wholesale in the admin menu and set your discount percentage. Submit a test application using an email address you control, check that the admin notification arrives, click approve, then log in as the new wholesale account and verify that prices show the discount and the label.
Two follow-up prompts worth having ready: 'Add a VAT number field to the registration form and include it in the admin notification email' is the most common extension. 'Add a Wholesale Accounts admin page listing all pending and approved accounts with their company names and an approve button per row' gives you a single place to manage the roster without going through the standard Users screen.
Questions
- Can a declined applicant reapply?
Yes. The plugin deletes the WordPress account on decline, so the email address is free again. A new application creates a fresh account and sends the admin another notification to review.
- What happens if someone applies with an email that already has a WordPress account?
The shortcode checks for an existing user with that email and shows an error asking them to log in or use a different address. No duplicate account is created.
- Where do I set the discount percentage?
Under WooCommerce > Wholesale in the admin menu. The default is 10 percent. Changing and saving the value takes effect immediately on all price displays without touching individual products.
- Does the discount apply in the cart and at checkout?
Yes. The plugin hooks into WooCommerce's price retrieval functions, which WooCommerce uses for the shop page, product pages, cart totals and the checkout. The order total the customer sees and the amount charged are both the discounted figure.
- Can I add extra fields to the application form?
That is a short follow-up prompt. Tell Steem which fields you need, such as a VAT number, business type or estimated monthly spend, and ask it to add them to the form, store them in user meta and include them in the admin notification email.
The prompt
Loads into the composer so you can edit it first. Nothing is built, and nothing is charged, until you send it.
Build a WooCommerce plugin that adds wholesale registration with manual approval. Register two custom WordPress user roles: wholesale_pending and wholesale_customer. Add a [wholesale_registration] shortcode that renders a front-end form with fields for company name, contact name, email, phone and a business description textarea. On valid form submission: if no WordPress user exists for that email, create one with the username derived from the email, assign the wholesale_pending role, store company name and business description in user meta with keys _wholesale_company and _wholesale_description, and send an email to get_option('admin_email') containing the applicant's details and two admin URLs constructed with add_query_arg and wp_nonce_url pointing to admin.php with a custom action parameter (wholesale_approve or wholesale_decline) and the user ID; then display a success message on the page. If an account already exists for that email, display an error message. Handle both admin actions in admin_init: verify the nonce, then for wholesale_approve change the user role to wholesale_customer using WP_User::set_role and send a welcome email to the user; for wholesale_decline delete the user with wp_delete_user and send a short rejection email to the applicant. Add a submenu page under the WooCommerce admin menu called Wholesale with a single settings field for wholesale_discount_percent using the Settings API, defaulting to 10. Hook into woocommerce_product_get_price and woocommerce_product_get_regular_price with priority 99 to multiply the price by (1 - discount/100) when the current user has the wholesale_customer role. Filter woocommerce_get_price_html to append a span with class wholesale-price-label and text Wholesale price for wholesale_customer users. Register all hooks inside a function attached to plugins_loaded.
Steem