Configuration
Pair Pro stores its settings in the pair_pro_settings option. The settings page is available under WooCommerce → Pair Pro and requires the manage_woocommerce capability.
Block settings
Section titled “Block settings”- Enable (
enabled), the master switch. When off, Pair Pro renders nothing on the storefront. - Heading (
heading), shown above the block. Defaults to “Frequently bought together”. Leave it blank to render the grid without a heading. - Products (
count), how many co-purchased products to show, clamped from 1 to 6. - Columns (
columns), clamped from 1 to 6. - Add all to cart (
add_all), shows a one-click button that adds every product in the block to the cart. - In stock only (
in_stock_only), excludes out-of-stock products from the results. - Orders to analyse (
scan_orders), how many of the most recent paid orders are scanned for co-purchases, clamped from 20 to 1000. Defaults to 150. - Bundle discount (
bundle_discount), the percentage taken off when the whole set is in the cart, clamped from 0 to 90. Defaults to 0, which means no discount.
Recommendation settings
Section titled “Recommendation settings”- Manual curation (
manual_enabled), on by default, adds a Pair recommendations meta box to the product editor. - Curation mode (
manual_mode), eitherprepend(hand-picked products lead, automatic picks fill the rest) orreplace(only the hand-picked products). Defaults toprepend. - Category rules (
rules_enabled,category_rules), off by default. Up to 6 rules, each a “when in category A, show category B” pair. - A/B testing (
ab_enabled), off by default, with Variant B strategy (ab_strategy_b), one ofrelated,tags,bestsellersornewest. Defaults tobestsellers. - Analytics (
analytics_enabled), on by default, records impressions, clicks and click-attributed add-to-cart events. - Thank-you page (
place_thankyou), on by default, and Checkout (place_checkout), off by default, with a shared Placement heading (place_heading) that defaults to “You may also like”.
Bundle discount
Section titled “Bundle discount”When the shopper uses Add all to cart, the set’s product IDs are stored in the WooCommerce session. On every fee calculation (woocommerce_cart_calculate_fees), Pair Pro checks that every product from that set is still in the cart and, if so, applies the percentage as a negative cart fee. Remove any one of them and the discount drops off at the next recalculation, and the stored set is cleared.
Manual curation
Section titled “Manual curation”With curation on, the product editor gets a Pair recommendations meta box where you pick products for that specific product. The selection is stored in the _pair_manual_recommendations post meta and merged in through the free plugin’s pair/recommendations filter, so it applies to the “You may also like” block on the product page. prepend puts your picks first and lets the automatic ones fill the remaining slots; replace shows only your picks.
Category rules
Section titled “Category rules”A rule reads “when the product is in category A, recommend products from category B”. Rules are global, defined on the settings page, capped at six, and applied to the single-product placement through the same pair/recommendations filter, leading the automatic picks.
Extra placements
Section titled “Extra placements”Beyond the free plugin’s product-page and cart blocks, Pair Pro can render recommendations on the order-received page (woocommerce_thankyou, priority 20) and after the checkout form (woocommerce_after_checkout_form, priority 20). Both reuse the free recommender and the same .pair-recommendations markup with a data-pair-context attribute, so theme styling and analytics apply unchanged.
Editor block
Section titled “Editor block”Pair Pro registers a server-rendered block, Pair Recommendations (pair-pro/recommendations), for the block editor and FSE templates. Its attributes are heading (defaults to “You may also like”), strategy (related, tags, bestsellers or newest, defaults to related) and count (defaults to 4). It supports wide and full alignment and renders through the free recommender with the context block.
A/B testing
Section titled “A/B testing”Each visitor is assigned a sticky variant in the pair_pro_ab cookie (30 days, SameSite=Lax), split at random on first visit. Variant A keeps the configured product-page strategy; variant B swaps in ab_strategy_b through the pair/recommendations filter. The analytics script appends the variant to the placement context, so the dashboard lists You may also like (variant A) and (variant B) as separate rows and you can compare them side by side.
Analytics
Section titled “Analytics”The storefront script reports impressions and clicks to a REST endpoint (pair-pro/v1/track). When a clicked product is later added to the cart, the click cookie (pair_pro_clicked) lets Pair Pro attribute an add-to-cart to that recommendation. Counts are aggregated on write into a single table, {prefix}pair_pro_stats, by day, placement and product, so the table stays small.
WooCommerce → Pair Pro Analytics shows impressions, clicks and click-attributed conversions per placement over a selectable date range, defaulting to the last 30 days. Placements are reported separately: You may also like (product page), Cart cross-sell, Frequently bought together, Thank-you page, Checkout, Block placement, and the two A/B variants.
Attribution is click-based and approximate. Treat it as a directional signal about which placement earns attention, not as revenue accounting.
How the scan works
Section titled “How the scan works”For each viewed product, Pair Pro fetches the most recent orders with status completed or processing (up to the configured scan depth), keeps the orders that contain the viewed product, and counts how often each other product appears alongside it. Order lines are attributed to their parent product, so variations of the same product collapse into one recommendation. Products are ranked by co-purchase count, highest first.
The ranked list (up to 12 products) is cached in a transient (pair_pro_fbt_<product id>) for 12 hours per product, so the scan runs at most once per cache window regardless of the configured count.
Recommended products must be published, visible in the catalog and, with the default filter on, in stock. The block hides itself entirely when no co-purchase data survives the filters.
Placement and markup
Section titled “Placement and markup”The block hooks into woocommerce_after_single_product_summary at priority 14, one step before the free “You may also like” block at 15, so it always renders above it. It reuses the free plugin’s .pair-recommendations markup with a --bought-together modifier and renders products through WooCommerce’s product loop template, so it inherits the active theme’s product cards. Pair Pro adds one small stylesheet that depends on the free Pair stylesheet. The block itself needs no frontend JavaScript; with analytics on, one small script is loaded to report impressions and clicks.
Add all to cart
Section titled “Add all to cart”The button submits a plain POST form protected by a nonce. On submit, Pair Pro adds each product from the block to the cart, skipping anything that is not purchasable or not in stock, shows the standard WooCommerce added-to-cart message and redirects back to the page you came from. Because it is a normal form post, it works with JavaScript disabled.
Storage and uninstall
Section titled “Storage and uninstall”Pair Pro stores:
pair_pro_settingspair_pro_versionpair_pro_activated_atpair_pro_db_versionpair_pro_fbt_<product id>transients (the 12-hour co-purchase cache){prefix}pair_pro_stats, the aggregated analytics table_pair_manual_recommendationspost meta on the products you curate by hand
Deleting the plugin removes all of it: the four options, every cached pair_pro_fbt_* transient, the _pair_manual_recommendations meta and the {prefix}pair_pro_stats table, once for every site on a network. Because Freemius tracks the uninstall event itself and rejects plugins that ship an uninstall.php script, the cleanup runs on the SDK’s after_uninstall hook. To keep the data instead, return false from the pair-pro/uninstall/delete_data filter in a must-use plugin, which loads before the cleanup runs.
On the storefront the plugin sets two cookies: pair_pro_ab (30 days, SameSite=Lax, the sticky A/B variant, only when A/B testing is on) and pair_pro_clicked (30 minutes, SameSite=Lax, the clicked product IDs used for attribution, only when analytics is on). Both hold product IDs or a single letter, no personal data.
Developer hooks
Section titled “Developer hooks”Pair Pro boots when the free plugin fires pair/booted, registers its services in the shared Pair container and fires pair-pro/booted with the booted PRO instance once ready.