Shopify Merchant Diagnostics
Pricing
from $20.00 / 1,000 product diagnostics
Shopify Merchant Diagnostics
Diagnose Shopify feed disagreements with original HTTP offers and rendered variant, currency, price and stock evidence. Captures subscription purchase context, screenshots and load failures. Experimental beta with explicit theme selectors; unknown evidence stays inconclusive.
Pricing
from $20.00 / 1,000 product diagnostics
Rating
0.0
(0)
Developer
Saim Islam
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
Share
Find where a supplied merchant feed row disagrees with a Shopify product page. This beta captures the original HTTP response, matches its structured offer, and samples the rendered product's price, currency, variant and purchase state in Chromium.
Use it to investigate price mismatches, sold-out pages, delayed subscription widgets and variant selection problems. The report preserves uncertainty and relevant page failures so a working browser page cannot silently become a clean verdict.
Quick start
- Run the example input to see the report format. The example is a saved public merchant feed row; the Actor does not fetch a feed or connect to Google Merchant Center.
- Replace
feedwith an actual row from your exported feed. Use separate decimalpriceand ISOcurrency, plusavailability,link, andvariant_idorsku. - Configure the product's selectors and exact resource origins. Selectors are specific to the store/theme. This beta does not automatically configure arbitrary themes.
- Open Results and Run summary. The default key-value store contains source HTML, rendered HTML, a screenshot and the complete report for each product.
No store account or Google account is required. Runs use fresh browser contexts without signed-in sessions. Start with one product and the example's 2 GB memory setting.
Inputs
Each entry in products contains:
| Field | Meaning |
|---|---|
feed | price, currency, availability, link, and variant_id or sku; optional id, mpn, sale_price, sale_price_effective_date, selling_plan_id |
selectors.root | One product container; body is usable when the other selectors uniquely identify the product |
selectors.price | The visible price for the selected purchase option; avoid crossed-out regular prices |
selectors.currency | Optional visible ISO currency label; a bare $ cannot establish USD |
selectors.variant | The selected variant control inside the product form; required when a variant is expected |
selectors.purchase | Optional bound cart button; recommended for verified rendered availability |
selectors.availability | Optional explicit visible stock label |
selectors.variant_data | Optional DOM JSON block declaring inventory and selling-plan allocations; script application/json or an explicit textarea JSON block |
selectors.variant_data_assignment | Optional plain assignment identifier for JSON embedded in a script; parsing never executes the script |
selectors.sku, selectors.locale | Optional visible SKU and number locale; default locale en-US |
allowed_origins | 1–40 exact HTTPS origins permitted for GET/HEAD resource loading, including the product origin |
sample_ms | 2–10 increasing offsets after DOMContentLoaded, between 0 and 10000 ms |
feed_provenance | Optional record of where and when the supplied row was obtained |
Top-level navigationTimeoutSeconds is 5–60 (default 45); maxRunSeconds is 30–600 (default 180). A run checks 1–10 products sequentially. Input is capped at 200 KB. Choose a platform timeout at least as long as maxRunSeconds.
A price inside an open shadow root can use an explicit >>> boundary. For example, recharge-subscription-widget >>> .rc-purchase-option:has(input[name="purchaseOption"]:checked) .rc-price:not(.strike-through) reads the selected Recharge price. Closed shadow roots are unsupported.
mpn matches explicit structured-data MPN identity; it is never converted to SKU. An arbitrary feed item ID does not establish a SKU. Record any enrichment of feed identity in feed_provenance.
Sale windows use start/end ISO timestamps. Only an active sale_price replaces price. Invalid or conflicting identities fail validation. A selling-plan expectation must match the URL's selling_plan when both are supplied.
Reading the result
| Result | Interpretation |
|---|---|
consistent_in_sample | Required captured fields agree within the configured sample; unresolved load failures are absent |
mismatch | At least one observed disagreement or change during loading; inspect complete and unknown too |
inconclusive | Identity, a required field, capture or relevant loading evidence could not be established |
complete | All required comparisons and the scoped load audit completed; this is separate from whether values agree |
findings | Layer, field, expected value and observed value for each disagreement |
unknown | Reasons the comparison could not be completed |
warnings / load_audit | Positively identified out-of-scope telemetry or checkout failures, and unresolved failures that prevent completeness |
HTTP-source offers are matched by explicit variant, SKU or MPN evidence. Conflicting offers, ranges, missing currency and ambiguous selectors remain unknown. Prices are normalized decimal strings. Multiple samples expose changes; they do not establish behavior outside that time window.
Rendered stock and subscriptions
An enabled Add to cart button establishes orderability. Corroborated in_stock additionally requires the selected variant's declared Shopify-managed quantity, deny overselling policy and enough quantity for the current form. A disabled bound Sold Out button establishes out_of_stock. Busy or unbound controls remain unknown.
For a selected recurring subscription, the exact plan must have one allocation, declare recurring deliveries, have equal total and per-delivery price, and match the visible selected price. Prepaid plans, unknown allocations and inconsistent prices remain unsupported. Current declared variant stock does not verify future subscription deliveries.
A limited single-variant fallback supports themes that omit the sold-out option ID: one disabled Sold Out form, one disabled option without a value, and exactly one unavailable variant declared in a JSON block inside that same form, with an exact matching option title. The report labels this inferred identity. It cannot establish an enabled purchase or infer between multiple variants.
The purchase-context finding distinguishes a one-time expectation from a page that defaults to a selling plan. A subscription discount versus a regular-price expectation is not, by itself, proof that the merchant submitted an incorrect feed.
Evidence and limits
Each product saves source.html, rendered.html, rendered.png and report.json. Dataset rows identify the record keys and original-response SHA-256. OUTPUT records runtime version, browser and totals. Use JSON export for full nested evidence; the table is an overview.
The Actor permits HTTPS public destinations on port 443. Each connection resolves and pins a public IP, rejects private/reserved or mixed DNS answers, and keeps normal TLS certificate verification. POST requests and WebSockets are blocked; cart, checkout, login and customer actions are not performed. Some apps require those requests and will therefore remain inconclusive. Resource origins and browser samples are recorded in the report.
Known telemetry and isolated Shopify web-pixel failures are retained as scoped warnings. Unknown scripts, HTTP failures and unclassified errors remain blocking. A completed run can contain inconclusive products: process success means evidence was stored, not that the store is healthy.
This tool does not verify Google feed ingestion, crawling, account approval, checkout prices, regional fulfillment, warehouse inventory or future availability. Feed transport is not verified by this run. Supply a current, genuine feed row for a meaningful feed comparison. Example rows and live store values can change after capture.
Version 0.3 is an experimental diagnostic. Validation covers controlled error cases and a small set of real Shopify pages; it does not establish coverage of every Shopify theme. The configured beta price is $0.02 per stored product diagnostic, including inconclusive reports, plus $0.00005 per GB of run memory for Actor start (minimum one start event). Platform usage is included in this pricing model. Inspect the current Apify pricing panel before running; pricing can change. The Actor stops starting new products when the SDK reports that another result would exceed the run charge limit. No paying-demand claim is made.
The pinned Playwright 1.62.1 build includes a narrow guard in its service-worker blocker: opaque sandbox frames already deny access to navigator.serviceWorker, so that SecurityError is handled while registration remains blocked. Other exceptions and store-script errors are preserved. Upgrading Playwright requires reviewing this patch.