Add a make-an-offer button to WooCommerce products: a plugin you can build today
· 4 min read
A lot of WooCommerce stores sell things where the price is negotiable. Antiques, second-hand gear, handmade items, custom commissions. WooCommerce is built around fixed prices: you set one, the customer adds to cart, they pay. For stores where the answer to 'will you take less?' is sometimes yes, there is no built-in mechanism. The customer has to find a contact page and hope the message gets through.
Themes like Astra surface this gap by shipping a Make an Offer button in their WooCommerce product templates. The button is there cosmetically. What is not there is anything to receive the offer. Astra's documentation points to paid add-ons. The same pattern repeats across themes: the UI exists, the backend does not, and closing that gap costs a subscription.
The backend is about forty lines of PHP. A button on the product page, an overlay form that collects the offer details, an AJAX handler that validates and emails them to you, and a thank-you message when it works. No database. No settings page. Here is the prompt that builds it.
What one build gives you
- Make an Offer button on every WooCommerce single product page, placed after the Add to Cart button
- Overlay form collecting name, email, offered price, and an optional message from the visitor
- AJAX submission with nonce verification and server-side field validation before the email is sent
- Admin notification email with product name, product URL, offered price, and all customer-submitted fields
What it does not do
- Counter-offer workflow: the negotiation happens by email or phone after the offer arrives
- Offer history in WordPress: all records are in your email inbox, not the admin
- Per-product enable or disable: the button appears on all products by default
- Customer confirmation email: only the admin is notified when an offer is submitted
- Minimum offer threshold: any number the visitor enters is accepted as a valid submission
YITH WooCommerce Make an Offer 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 WordPress plugin that adds a Make an Offer button to all WooCommerce single product pages. Hook into woocommerce_after_add_to_cart_button to render a button labelled 'Make an Offer'. When clicked, the button opens a full-screen overlay containing a form with four fields: Name (text input, required), Email (email input, required), Offered Price (number input, min 0.01, step 0.01, required), and Message (textarea, optional, placeholder 'Any questions or context about your offer'). Include a close button in the top-right corner of the overlay. On submit, use AJAX with a nonce created by wp_create_nonce to send the data to a PHP handler registered with wp_ajax_nopriv_submit_make_offer and wp_ajax_submit_make_offer. The handler verifies the nonce with wp_verify_nonce, checks that all required fields are present, sanitizes inputs with sanitize_text_field, sanitize_email, and floatval, retrieves the product title and permalink from the posted product ID, and sends a notification email to get_option('admin_email') using wp_mail. The email subject is 'New offer on [product title]'. The body is plain text with line breaks: 'Product: [title]', 'URL: [permalink]', 'Offered price: [price]', 'Name: [name]', 'Email: [email]', 'Message: [message]'. Return wp_send_json_success on success or wp_send_json_error with a message string on failure. On a success response, replace the form inside the overlay with the message 'Thank you. We have received your offer and will be in touch shortly.' and a Close button. On an error response, show the error message below the submit button without closing the overlay. Enqueue the JavaScript with wp_enqueue_script and add the overlay CSS with wp_add_inline_style. The overlay uses position fixed, covers the full viewport, has a semi-transparent dark background, and contains a centred white box with padding. Form fields are stacked with visible labels above each input. Do not write to the database. Do not add a settings page or admin menu.
Why WooCommerce does not have this built in
WooCommerce assumes the price is fixed. The entire checkout flow is built around that: a price is set, a cart is built, the cart is paid. Variable pricing is handled by product variations, sales, and coupons, but all of those are still fixed at the moment of purchase.
Negotiated pricing breaks that model. The price is not known until after a conversation. That conversation has to happen somewhere, and most stores handle it by email or phone after the customer has already left the product page. A make-an-offer form keeps the customer on the page and starts the conversation immediately.
What the plugin builds
The plugin adds a Make an Offer button to every WooCommerce single product page using the woocommerce_after_add_to_cart_button hook, so it appears directly below the Add to Cart button. Clicking it opens a full-screen overlay with a short form: Name, Email, Offered Price, and an optional message field.
The form submits via AJAX with a nonce for security. The PHP handler validates the required fields, sanitizes every input, and sends an email to the WordPress admin address using wp_mail. The subject line is 'New offer on [product name]' and the body lists the offered price, the customer's name and email, their message, and a link to the product. The overlay then replaces the form with a short thank-you message.
No database writes. No admin screen. Offers land in your inbox alongside everything else.
Who this is for
Any store where negotiation is part of the sale. Antiques and collectibles, where condition and provenance affect value. Vintage clothing, instruments, and used camera gear. Handmade or custom items where the listed price is a starting point. Art and prints where editions and sizes vary. B2B stores where the price depends on order volume.
It also works well on consignment or resale pages where the seller wants to hear what the market will pay before committing to a price. Put the button next to the listed price and see what comes in.
Who should use a different approach
If you need a counter-offer workflow inside WordPress, where the customer submits a price, you respond with a counter, and the whole negotiation is tracked in a WooCommerce order, that is a much larger build. YITH WooCommerce Make an Offer handles that flow with a proper order status for pending offers. This plugin sends an email; you negotiate outside it.
If you need offer records stored in WordPress for reporting or handoff to a sales team, this plugin does not do that. Offers live in your email inbox. Gravity Forms with its built-in entry storage and notification system is the right tool if you need both a form log and an email.
If you need the button on specific products only, the default build enables it everywhere. Per-product control is a small follow-up: ask Steem to add a checkbox to each product's edit screen that hides the button when unchecked.
How to build it
Paste the prompt below into Steem. The plugin downloads as a zip and installs under Plugins > Add New > Upload Plugin. Once active, visit any product page: the Make an Offer button appears below Add to Cart. Submit a test offer to confirm the admin email arrives correctly.
Two common follow-ups: 'add a minimum offer amount, and show an inline error if the visitor enters less' stops low-ball submissions before they reach your inbox. 'Add a checkbox on each product edit screen to hide the Make an Offer button on that product' gives per-product control. Either one takes a single message in Steem.
Questions
- Will this work with variable products?
- Yes. The button appears on variable product pages the same as on simple products. The notification email includes the product name. If you want the selected variation included in the email, ask Steem to read the variation ID from a hidden field populated by WooCommerce's variation selection script.
- Where do offers go?
- To the WordPress admin email address set under Settings > General. If you use a shared admin account, ask Steem to add a dedicated notification address to the plugin so offers can go to a specific inbox.
- Can customers see the offers they have submitted?
- No. The plugin sends an email and shows a thank-you message. There is no customer account integration or offer history. If that matters, Gravity Forms with the User Submission addon is closer to what you need.
- Will it work with my theme?
- Any theme that uses WooCommerce's standard single product template will show the button. If your theme overrides the product template entirely without calling the woocommerce_after_add_to_cart_button hook, the button will not appear. Most major themes call the hook correctly.
- Can I hide the button on specific products?
- Not with the default build. It is a common follow-up: ask Steem to add a checkbox on each product's edit screen that hides the Make an Offer button when unchecked. A single message is enough.
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 WordPress plugin that adds a Make an Offer button to all WooCommerce single product pages. Hook into woocommerce_after_add_to_cart_button to render a button labelled 'Make an Offer'. When clicked, the button opens a full-screen overlay containing a form with four fields: Name (text input, required), Email (email input, required), Offered Price (number input, min 0.01, step 0.01, required), and Message (textarea, optional, placeholder 'Any questions or context about your offer'). Include a close button in the top-right corner of the overlay. On submit, use AJAX with a nonce created by wp_create_nonce to send the data to a PHP handler registered with wp_ajax_nopriv_submit_make_offer and wp_ajax_submit_make_offer. The handler verifies the nonce with wp_verify_nonce, checks that all required fields are present, sanitizes inputs with sanitize_text_field, sanitize_email, and floatval, retrieves the product title and permalink from the posted product ID, and sends a notification email to get_option('admin_email') using wp_mail. The email subject is 'New offer on [product title]'. The body is plain text with line breaks: 'Product: [title]', 'URL: [permalink]', 'Offered price: [price]', 'Name: [name]', 'Email: [email]', 'Message: [message]'. Return wp_send_json_success on success or wp_send_json_error with a message string on failure. On a success response, replace the form inside the overlay with the message 'Thank you. We have received your offer and will be in touch shortly.' and a Close button. On an error response, show the error message below the submit button without closing the overlay. Enqueue the JavaScript with wp_enqueue_script and add the overlay CSS with wp_add_inline_style. The overlay uses position fixed, covers the full viewport, has a semi-transparent dark background, and contains a centred white box with padding. Form fields are stacked with visible labels above each input. Do not write to the database. Do not add a settings page or admin menu.
Steem