=== Factorize Auctions ===
Contributors: webyoungstown
Tags: woocommerce, auction, bidding, liquidation, buy-now
Requires at least: 6.2
Tested up to: 6.7
Stable tag: 1.0.1
Requires PHP: 7.4
License: Factorize License (proprietary)
License URI: https://factorize.webyoungstown.com/license/

Weekly WooCommerce auctions that run themselves: auto relists, Buy Now gray-out, one-tap bidding, verified bidders, honest retail comparisons.

== Description ==

Auctions are great for moving liquidation stock — until you spend every Monday relisting the ones that did not sell, chasing winners who never pay, and answering "is this really below retail?" questions. Factorize Auctions automates the whole cycle on top of the free Ultimate Auction for WooCommerce plugin: every auction sells exactly one unit per cycle, an hourly tick relists failed cycles and forfeits ghost winners, and a paid order — Buy Now or winning bid — either puts the next unit up for a fresh cycle or ends the auction for good. On the storefront it adds the conversion layer a real auction store needs: one-tap bidding, a Buy Now button that grays out (instead of vanishing) once bidding passes it, bidder verification, and retail comparisons shoppers can check for themselves. Built for a real liquidation store and battle-tested on 950 live products.

= Features =

* **One unit per cycle** — every auction sells exactly one unit per cycle; a cycle ends by end date or by someone using Buy Now.
* **Automatic relisting** — an hourly tick rolls ended auctions forward: a failed cycle (no bids, or reserve not met) relists immediately for a fresh cycle with a clean slate and a cleared bid history.
* **Ghost-winner forfeit** — a winner who has not even started an order within the grace period (default 3 days) forfeits, and the auction relists so the unit is never stuck.
* **Sold-out finalize** — when the last unit is gone, the auction closes for good.
* **Paid-order handling** — an order that reaches processing, completed, or payment-complete and contains an auction product consumes one unit: the next unit relists for a fresh cycle if stock remains, otherwise the auction ends; a meta flag prevents double handling.
* **Buy Now with gray-out** — the product's regular price is the Buy Now amount (Ultimate Auction's own rule), so the two can never disagree. Once bidding passes it, this plugin renders a disabled Buy Now button that explains why — the option visibly grays out instead of silently disappearing. A quiet "or skip the bidding" divider keeps the two calls to action from reading as one.
* **Billing-details bid gate** — a bid is only accepted from a logged-in account with complete billing details (name, street address, city, ZIP, phone) on file — the strongest no-show deterrent available without a card vault. Unverified bidders get a clear notice with a one-click link to the billing form, both when they try to bid and up front on every auction page.
* **One-tap quick bid** — a button that already knows the next valid amount (current bid + increment, or the opening bid). The first tap arms a "Confirm" state that quietly disarms after 6 seconds; the bid submits through the real bid form, so every server-side rule still applies. The custom-amount input stays available for higher bids.
* **Retail-price comparison** — a "% below retail" line computed from the pinned retail price against the live price story (current bid when there is one, otherwise Buy Now), with a shopper-facing "source" link so the claim can be verified: a per-product listing URL, or a configurable search template (Google Shopping by default).
* **Auction card extras** — shop and archive cards get the Buy Now price line, the "% below retail" figure, and an "Ends in Xh Ym" urgency badge inside the final 24 hours.
* **Per-product returns modes** — a Returns dropdown on the product edit screen (Default / Returns accepted / As-is, no returns) with a matching storefront line; the default is as-is for auctions and a 7-day defect policy for regular products.
* **Inventory honesty note** — auction pages carry a disclaimer that inventory syncs daily and an in-store sale can end an auction early with nothing charged.
* **Less alarm noise** — the "reserve price has not been met" warning stays hidden until someone has actually placed a bid, instead of shouting at every auction that has not opened yet.
* **Fine-print fold** — the condition, pickup, returns, and inventory lines collapse into a single "Condition, pickup & policies" row so they stop crowding the buy box (can be disabled).
* **Factorize hub card** — registers a status card (showing the current cycle length) in the shared Factorize admin hub, under the Selling tab.
* **Clean uninstall** — deleting the plugin removes its options and scheduled event but never touches store history (products, bids, orders).

= Works standalone, better together =

Factorize is a modular WooCommerce toolkit for liquidation, bin, discount, and open-box stores, built and battle-tested on a real 950-product store. Every plugin works completely standalone; any of them alone stands up the shared "Factorize" admin hub, and together they fill it with category tabs (Insights / Selling / Customers / Storefront). Install Factorize Auctions by itself and you still get the full hub with its Auctions card; add siblings and they slot in beside it — for example, the hourly auction tick refreshes Factorize Catalog's Featured picks when that plugin is present. Every cross-plugin call is guarded, so a missing sibling just means that step is skipped.

= Configuration =

There is no settings screen to hunt through — the defaults are the values proven on the original store. Overrides live in the `factorize-auctions_options` option (an array in wp_options; override any subset of keys), and the merged config passes through the `factorize-auctions_config` filter. Values are read via `empire_auction_config( $key )`:

* `relist_grace_days` (default `3`) — days an auction winner gets to start an order before forfeiting the win.
* `fineprint_enabled` (default `true`) — set to false to print the policy lines unfolded instead of inside the collapsible row.
* `retail_source_template` (default: a Google Shopping search) — where the "source" link on "% below retail" points; `{query}` is replaced with the URL-encoded product title.

The cycle length comes from the separate `et_auction_days` option (default `7` days). Per product: the regular price is the Buy Now amount, `_et_retail_price` pins the retail price, `_et_retail_source` overrides the source link for that product, and `_et_returns_mode` is the Returns dropdown.

= Roadmap =

These features are planned for future releases and are NOT in the current version:

* Anti-sniping time extension
* Proxy / max-bid bidding UI
* Outbid email and SMS alerts
* Scheduled reserve drops
* Buy Now price decay
* Auction calendar page
* Winner checkout reminders

== Installation ==

1. Install and activate WooCommerce and the free Ultimate Auction for WooCommerce plugin. Factorize Auctions layers its lifecycle and storefront features on that plugin's `auction` product type and renders nothing without it.
2. Upload the `factorize-auctions` folder to `/wp-content/plugins/` (or install via Plugins → Add New) and activate. A **Factorize** menu appears in wp-admin; the Auctions card sits under the **Selling** tab and shows your current cycle length.
3. Create an auction product as usual in Ultimate Auction (opening price, bid increment, dates), then set its **regular price** — that is the Buy Now amount. Leave it empty to run a pure auction with no Buy Now.
4. Optional but worth it: add an `_et_retail_price` custom field to power the "% below retail" line, and pick a **Returns** mode in Product data → General (the default is as-is for auctions, 7-day defect policy for everything else).
5. Confirm the cycle: auctions relist for `et_auction_days` days (default 7); change it with e.g. `wp option update et_auction_days 5`. The hourly `et_auction_tick` event schedules itself about five minutes after activation — make sure WP-Cron actually runs (on low-traffic sites, point a real cron job at `wp-cron.php`).

== Frequently Asked Questions ==

= Does it work without the other Factorize plugins? =

Yes. Every Factorize plugin is fully standalone, and installing this one alone stands up the shared Factorize admin hub with the Auctions card in it. Cross-plugin calls — like refreshing Factorize Catalog's Featured picks from the hourly tick — are wrapped in function_exists() checks, so a missing sibling just means that step is skipped. Nothing breaks.

= Do I need a separate auction plugin? =

Yes: WooCommerce plus Ultimate Auction for WooCommerce, which provides the auction product type, bid form, and bid processing. Factorize Auctions adds what that plugin does not: the automated one-unit-per-cycle lifecycle, relisting and forfeits, the Buy Now gray-out, bidder verification, one-tap bidding, retail comparisons, and the returns/fine-print layer.

= Does any data leave my server? =

No. Everything runs locally in WordPress — no external API calls, no tracking, no phoning home. The only external URL involved is the shopper-facing "source" link on the retail comparison, which by default points to a Google Shopping search and only opens when a shopper chooses to click it.

= Where does the plugin's data live? =

In standard WordPress storage: product post meta (Ultimate Auction's `woo_ua_*` keys plus this plugin's `_et_*` keys), the `factorize-auctions_options` and `et_auction_days` options, and Ultimate Auction's own bid-log table (cleared per product on relist, so each fresh cycle starts with a clean Bids tab). Uninstalling deletes the plugin's options and its scheduled event, but deliberately keeps all store history.

= How do I change a default, like the 3-day winner grace period? =

Store an override in the `factorize-auctions_options` option — for example `update_option( 'factorize-auctions_options', array( 'relist_grace_days' => 5 ) );` — or hook the `factorize-auctions_config` filter. The auction length itself is the separate `et_auction_days` option.

= Why is the Buy Now button gray? =

For auction products the product price is the Buy Now amount, and buying is only possible while the highest bid is below it. Ultimate Auction removes its Buy Now button entirely at that point; Factorize Auctions fills the gap with a disabled button that says bidding has passed the Buy Now price — so shoppers see why the option went away instead of wondering where it went.

== Screenshots ==

1. Auction product page: the one-tap quick-bid button beside the bid form, the "% below retail" line with its source link, the "or skip the bidding" divider, and the folded "Condition, pickup & policies" row.
2. The grayed-out Buy Now button with its explanation, shown once bidding passes the Buy Now price.
3. Shop archive card extras: the Buy Now price line, "% below retail", and the "Ends in 3h 12m" badge inside the final day.
4. The billing-details bid gate: the notice an unverified bidder sees, with the one-click link to the billing address form.
5. The Factorize admin hub, Selling tab, with the Factorize Auctions status card showing the cycle length.

== Changelog ==

= 1.0.0 =
* Initial release.
* Automated one-unit-per-cycle auction lifecycle: hourly tick, automatic relists, ghost-winner forfeit, sold-out finalize, paid-order handling.
* Buy Now gray-out with explanation, plus the "or skip the bidding" divider.
* Billing-details bid gate with up-front verification notice on auction pages.
* One-tap quick bid with tap-again confirmation, submitted through the real bid form.
* Retail comparison ("% below retail") with a shopper-verifiable source link, on product pages and archive cards, plus the ends-soon badge.
* Per-product returns modes, inventory disclaimer, and the collapsible fine-print row.
