Skip to content

fix: prevent PWYW pricing type from being reset to free on save#831

Merged
superdav42 merged 1 commit intomainfrom
bugfix/pwyw-is-free-reset
Apr 14, 2026
Merged

fix: prevent PWYW pricing type from being reset to free on save#831
superdav42 merged 1 commit intomainfrom
bugfix/pwyw-is-free-reset

Conversation

@superdav42
Copy link
Copy Markdown
Collaborator

@superdav42 superdav42 commented Apr 14, 2026

Summary

  • Bug: Setting a product's pricing type to "Pay What You Want" silently reverted to "Free" on save when the suggested/minimum amounts were $0
  • Root cause: Product::is_free() returned true for PWYW products with $0 amounts, triggering the save() guard that auto-normalizes free products
  • Fix: PWYW products are never "free" by definition — the customer decides the price. is_free() now returns false for PWYW, and the save() guard is narrowed to only normalize the paid type

Reproduction

  1. Network Admin → Products → Add New
  2. Set Pricing Type to "Pay What You Want"
  3. Leave Minimum/Suggested Price at $0
  4. Save → pricing type silently changed to "Free"

Changes

  • inc/models/class-product.php
    • is_free(): early return false for PWYW products
    • save(): guard condition narrowed from !== 'contact_us' to === 'paid'

Testing

  • 183 existing Product_Test assertions pass
  • Verified via WP-CLI: PWYW with $0 amounts, PWYW with non-zero amounts, paid $0→free normalization, contact_us preservation, existing product→PWYW conversion
  • Verified in browser: new product with PWYW/$0 persists correctly through multiple saves

Summary by CodeRabbit

  • Bug Fixes
    • Fixed product pricing logic to correctly classify Pay What You Want products, preventing them from being incorrectly treated as free items.
    • Improved product pricing type validation to ensure consistent handling when saving product configurations.

Product::is_free() treated Pay What You Want products with $0
suggested/minimum amounts as free, causing Product::save() to
silently override the pricing_type to 'free'. A PWYW product is
by definition not free — the customer decides the price.

- Add early return in is_free() for PWYW products
- Narrow save() guard to only normalize 'paid' type to 'free'
@superdav42 superdav42 added the origin:interactive Created by interactive user session label Apr 14, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 14, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d920d457-0b68-4f32-9c9b-b9537418a089

📥 Commits

Reviewing files that changed from the base of the PR and between 1273ffa and 3b56c86.

📒 Files selected for processing (1)
  • inc/models/class-product.php

📝 Walkthrough

Walkthrough

Updated Product::is_free() to explicitly return false for Pay What You Want products regardless of suggested/minimum amounts being zero. Modified Product::save() to restrict pricing type normalization to 'free' only when the product is free and the current type is exactly 'paid', rather than allowing transitions from other non-contact_us types.

Changes

Cohort / File(s) Summary
Pricing Logic Refinements
inc/models/class-product.php
Updated is_free() to guard against PWYW products being incorrectly classified as free. Refined save() method's pricing type normalization to only transition from 'paid' to 'free', preventing unintended transitions from other pricing types.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 A PWYW guard stands tall and true,
No false "free" claims slip through!
Pricing types now know their place,
From paid to free at steady pace. ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main bug fix: preventing PWYW pricing type from being reset to free on save, which directly matches the changeset's primary objectives.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch bugfix/pwyw-is-free-reset

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown

🔨 Build Complete - Ready for Testing!

📦 Download Build Artifact (Recommended)

Download the zip build, upload to WordPress and test:

🌐 Test in WordPress Playground (Very Experimental)

Click the link below to instantly test this PR in your browser - no installation needed!
Playground support for multisite is very limitied, hopefully it will get better in the future.

🚀 Launch in Playground

Login credentials: admin / password

@github-actions
Copy link
Copy Markdown

Performance Test Results

Performance test results for c662239 are in 🛎️!

Note: the numbers in parentheses show the difference to the previous (baseline) test run. Differences below 2% or 0.5 in absolute values are not shown.

URL: /

Run DB Queries Memory Before Template Template WP Total LCP TTFB LCP - TTFB
0 41 37.83 MB 932.50 ms (+63.50 ms / +7% ) 165.50 ms (+12.50 ms / +8% ) 1085.00 ms (+25.50 ms / +2% ) 2096.00 ms 2010.20 ms (+45.70 ms / +2% ) 88.70 ms (-6.85 ms / -8% )
1 56 49.02 MB 918.50 ms 146.50 ms 1065.00 ms 2058.00 ms 1975.90 ms 81.60 ms (-1.90 ms / -2% )

@superdav42 superdav42 merged commit 1350b0f into main Apr 14, 2026
11 checks passed
@superdav42
Copy link
Copy Markdown
Collaborator Author

Summary

  • Bug: Setting a product's pricing type to "Pay What You Want" silently reverted to "Free" on save when the suggested/minimum amounts were $0
  • Root cause: Product::is_free() returned true for PWYW products with $0 amounts, triggering the save() guard that auto-normalizes free products
  • Fix: PWYW products are never "free" by definition — the customer decides the price. is_free() now returns false for PWYW, and the save() guard is narrowed to only normalize the paid type

Reproduction

  1. Network Admin → Products → Add New
  2. Set Pricing Type to "Pay What You Want"
  3. Leave Minimum/Suggested Price at $0
  4. Save → pricing type silently changed to "Free"

Changes

  • inc/models/class-product.php
    • is_free(): early return false for PWYW products
    • save(): guard condition narrowed from !== 'contact_us' to === 'paid'

Testing

  • 183 existing Product_Test assertions pass
  • Verified via WP-CLI: PWYW with $0 amounts, PWYW with non-zero amounts, paid $0→free normalization, contact_us preservation, existing product→PWYW conversion
  • Verified in browser: new product with PWYW/$0 persists correctly through multiple saves

Merged via PR #831 to main.
Merged by deterministic merge pass (pulse-wrapper.sh).


aidevops.sh v3.8.17 spent 9m on this as a headless bash routine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

origin:interactive Created by interactive user session

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant