Module: Catalog::AmazonCompetitiveSignal
- Defined in:
- app/services/catalog/amazon_competitive_signal.rb
Overview
Reads the two competitive numbers out of an Amazon buy-box Summary payload
and says which of them is allowed to move a price.
They are not interchangeable, and treating them as one number is what this
module exists to stop:
CompetitivePriceThresholdis Amazon's benchmark for what counts as a
competitive price on the ASIN, derived from the wider market. It is
evidence, so it binds.SuggestedLowerPricePlusShippingis Amazon asking us to charge less.
Its whole purpose is to sit below what we currently charge, so it is a
negotiating position, not evidence of anyone's price. It is advisory.
Until 2026-08-04 five call sites took [threshold, suggestion].compact.min.
Because the suggestion is by construction the lower of the two, it won
whenever Amazon sent one, and the repricer inherited Amazon's opinion instead
of the market's. On PTC120-7W-012-WY (B09YSZ5VVG, catalog item 43151) that
read as a competitor at $63.75 while the real benchmark was $71.25 — matching
Home Depot Canada to the cent — and NumberOfOffers was 1, so there was no
competitor on the listing at all.
It also closed a loop: AmazonBuyBoxService#fair_pricing_correction stepped
the price down toward the suggestion (71.24 → 67.68 → 64.30 over 08-01 and
08-03), and then AmazonPriceRaisingService refused to raise it because the
same suggestion now sat below the price, reporting the block to operators as
"an external retailer has a lower or equal price". 53 automated reductions
across two runs, $356.76 of price removed, 24 of the affected listings with no
competing offer.
Class Method Summary collapse
-
.advisory_suggestion(summary) ⇒ Float?
Amazon's suggested lower price.
-
.binding_threshold(summary) ⇒ Float?
The competitive number a price decision may act on.
Class Method Details
.advisory_suggestion(summary) ⇒ Float?
Amazon's suggested lower price. Reportable, never a reason to move a price.
57 58 59 60 61 62 |
# File 'app/services/catalog/amazon_competitive_signal.rb', line 57 def advisory_suggestion(summary) return nil if summary.blank? value = summary.dig(:SuggestedLowerPricePlusShipping, :Amount)&.to_f value if value&.positive? end |
.binding_threshold(summary) ⇒ Float?
The competitive number a price decision may act on.
Zero is treated as absent: Amazon omits these keys rather than sending 0,
so a 0.0 here means a malformed or empty payload, and letting it through
would present a $0 floor as the market rate.
46 47 48 49 50 51 |
# File 'app/services/catalog/amazon_competitive_signal.rb', line 46 def binding_threshold(summary) return nil if summary.blank? value = summary.dig(:CompetitivePriceThreshold, :Amount)&.to_f value if value&.positive? end |