{"id":308942,"date":"2026-05-17T22:04:51","date_gmt":"2026-05-17T22:04:51","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/precision-live-rates-for-woocommerce\/"},"modified":"2026-05-17T22:04:40","modified_gmt":"2026-05-17T22:04:40","slug":"precision-live-rates-for-woocommerce","status":"publish","type":"plugin","link":"https:\/\/wordpress.org\/plugins\/precision-live-rates-for-woocommerce\/","author":14971057,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"0.2.39","stable_tag":"0.2.39","tested":"6.9.4","requires":"6.4","requires_php":"8.2","requires_plugins":null,"header_name":"Precision Live Rates for WooCommerce","header_author":"Suleman Shahjahan","header_description":"Live carrier rates from UPS, USPS, FedEx, DHL, and Stamps.com via ShipEngine, with deterministic 3D bin-packing and a unified cart-to-checkout pipeline.","assets_banners_color":"fefefe","last_updated":"2026-05-17 22:04:40","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/github.com\/sulemanshahjahan\/precision-live-rates-for-wooCommerce","header_author_uri":"https:\/\/github.com\/sulemanshahjahan","rating":0,"author_block_rating":0,"active_installs":0,"downloads":38,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"0.2.39":{"tag":"0.2.39","author":"sulemanshahjahan","date":"2026-05-17 22:04:40"}},"upgrade_notice":{"0.2.39":"<p>Hardens output escaping in the onboarding wizard&#039;s text-field renderer and fixes two more 404 URLs in the readme. No user-visible behavior changes.<\/p>","0.2.38":"<p>Restores the admin-page styling that 0.2.37 inadvertently disabled when the text domain was renamed. Upgrade is mandatory for anyone who installed 0.2.37.<\/p>","0.2.37":"<p>Text domain renamed to match the WP.org-assigned plugin slug. No user-visible behavior changes; existing translations on translate.wordpress.org now resolve correctly. Settings and box catalog carry over.<\/p>","0.2.36":"<p>Upgrades dvdoug\/boxpacker from 3.x to 4.x and bumps the minimum PHP version from 8.1 to 8.2 (the new boxpacker requires it). Sanitizes the box-catalog allowed_carriers POST field. No user-visible behavior changes.<\/p>","0.2.35":"<p>WP.org reviewer remediation: removed all premium-tier \/ license-key code, renamed the internal PHP namespace, tightened nonce sanitization, scrubbed comparative marketing from the description. No user-facing behavior changes. Existing settings carry over.<\/p>","0.2.34":"<p>Slug renamed <code>wc-precision-rates<\/code> \u2192 <code>precision-live-rates<\/code> to clear the WP.org trademark warning. <strong>Settings reset on upgrade<\/strong> \u2014 option\/transient prefix changed, so origin, markups, box catalog, and API keys must be re-entered. Onboarding wizard re-launches automatically.<\/p>","0.2.33":"<p>WP.org Plugin Check round 2 cleanup. Uses $wpdb-&gt;insert() for the audit-log INSERT; drops the now-redundant load_plugin_textdomain() call. No behavior changes.<\/p>","0.2.32":"<p>WP.org Plugin Check remediation. No behavior changes.<\/p>","0.2.31":"<p>Internal infrastructure work. No user-facing changes.<\/p>","0.2.30":"<p>Adds delivery-date badges and carrier logos to cart\/checkout (both default ON) plus an optional free-shipping threshold. Existing installs see the badges\/logos appear automatically; the threshold defaults to 0 (disabled).<\/p>","0.2.29":"<p>Adds an Audit log tab + custom DB table. Schema bootstraps automatically; no merchant action required.<\/p>","0.2.28":"<p>Adds Canadian + UK postal-code \u2192 province\/region inference. Existing US installs see no behavior change; international quotes now include state_province by default.<\/p>","0.2.27":"<p>WordPress.org submission prep \u2014 plugin header now declares the real Author + Plugin URI, no behavior changes, safe to upgrade.<\/p>","0.2.26":"<p>Documentation polish for WordPress.org submission readiness \u2014 no behavior changes, safe to upgrade.<\/p>","0.2.25":"<p>Adds GDPR-compliant privacy disclosure surface. EU\/UK merchants should turn on Settings \u2192 Privacy \u2192 &quot;Display privacy disclosure on cart\/checkout&quot; after upgrading.<\/p>","0.2.24":"<p>Spanish + French translations now bundled. Set site language under Settings \u2192 General to switch UI locale. No behavior changes for English installs.<\/p>","0.2.22":"<p>Adds an onboarding wizard for new installs. Existing installs with populated settings are auto-marked onboarded \u2014 your existing config will not be touched.<\/p>"},"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3534890,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3534890,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3534890,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3534890,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["0.2.39"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3534890,"resolution":"1","location":"assets","locale":"","width":1280,"height":855},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3534890,"resolution":"2","location":"assets","locale":"","width":1291,"height":788},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3534890,"resolution":"3","location":"assets","locale":"","width":1280,"height":1179},"screenshot-4.png":{"filename":"screenshot-4.png","revision":3534890,"resolution":"4","location":"assets","locale":"","width":1280,"height":984},"screenshot-5.png":{"filename":"screenshot-5.png","revision":3534890,"resolution":"5","location":"assets","locale":"","width":1280,"height":855},"screenshot-6.png":{"filename":"screenshot-6.png","revision":3534890,"resolution":"6","location":"assets","locale":"","width":1280,"height":1211},"screenshot-7.png":{"filename":"screenshot-7.png","revision":3534890,"resolution":"7","location":"assets","locale":"","width":1280,"height":855}},"screenshots":{"1":"Overview tab \u2014 at-a-glance plugin status, active carriers, cache TTL, markup configuration, and quick-action buttons (clear cache, run rate test, manage services, open settings, re-run onboarding).","2":"Settings tab \u2014 origin address, ShipEngine + UPS + USPS connections with inline Test Connection, packing toggle, per-carrier markup, cache TTL, privacy disclosure toggle.","3":"Services tab \u2014 auto-discovered <code>carrier:service_code<\/code> whitelist with diagnostic counts (\"Filter state: N enabled, M disabled\") so the merchant can verify saves persisted.","4":"Rate test tab \u2014 quote against your live carrier configuration without leaving the admin. Shows final rates with markup applied PLUS the raw ShipEngine request and response inline (collapsible).","5":"Cart with live rates \u2014 UPS Ground, USPS Priority Mail, FedEx Ground rendering at the merchant's chosen markup, with optional EU\/UK privacy disclosure line.","6":"Onboarding wizard \u2014 first-activation 4-step flow that takes a merchant from \"just clicked Activate\" to \"first rate quoted\" in under three minutes.","7":"Audit log \u2014 append-only record of state-changing admin actions (settings saves, box CRUD, service-filter changes, cache clears, ShipEngine connection tests). Filter by event type, paginate, export to CSV."},"jetpack_post_was_ever_published":false},"plugin_section":[],"plugin_tags":[193847,203168,3546,5555,3519],"plugin_category":[45],"plugin_contributors":[263292],"plugin_business_model":[],"class_list":["post-308942","plugin","type-plugin","status-publish","hentry","plugin_tags-live-rates","plugin_tags-shipengine","plugin_tags-shipping","plugin_tags-ups","plugin_tags-usps","plugin_category-ecommerce","plugin_contributors-sulemanshahjahan","plugin_committers-sulemanshahjahan"],"banners":{"banner":"https:\/\/ps.w.org\/precision-live-rates-for-woocommerce\/assets\/banner-772x250.png?rev=3534890","banner_2x":"https:\/\/ps.w.org\/precision-live-rates-for-woocommerce\/assets\/banner-1544x500.png?rev=3534890","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/precision-live-rates-for-woocommerce\/assets\/icon-128x128.png?rev=3534890","icon_2x":"https:\/\/ps.w.org\/precision-live-rates-for-woocommerce\/assets\/icon-256x256.png?rev=3534890","generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/precision-live-rates-for-woocommerce\/assets\/screenshot-1.png?rev=3534890","caption":"Overview tab \u2014 at-a-glance plugin status, active carriers, cache TTL, markup configuration, and quick-action buttons (clear cache, run rate test, manage services, open settings, re-run onboarding)."},{"src":"https:\/\/ps.w.org\/precision-live-rates-for-woocommerce\/assets\/screenshot-2.png?rev=3534890","caption":"Settings tab \u2014 origin address, ShipEngine + UPS + USPS connections with inline Test Connection, packing toggle, per-carrier markup, cache TTL, privacy disclosure toggle."},{"src":"https:\/\/ps.w.org\/precision-live-rates-for-woocommerce\/assets\/screenshot-3.png?rev=3534890","caption":"Services tab \u2014 auto-discovered <code>carrier:service_code<\/code> whitelist with diagnostic counts (\"Filter state: N enabled, M disabled\") so the merchant can verify saves persisted."},{"src":"https:\/\/ps.w.org\/precision-live-rates-for-woocommerce\/assets\/screenshot-4.png?rev=3534890","caption":"Rate test tab \u2014 quote against your live carrier configuration without leaving the admin. Shows final rates with markup applied PLUS the raw ShipEngine request and response inline (collapsible)."},{"src":"https:\/\/ps.w.org\/precision-live-rates-for-woocommerce\/assets\/screenshot-5.png?rev=3534890","caption":"Cart with live rates \u2014 UPS Ground, USPS Priority Mail, FedEx Ground rendering at the merchant's chosen markup, with optional EU\/UK privacy disclosure line."},{"src":"https:\/\/ps.w.org\/precision-live-rates-for-woocommerce\/assets\/screenshot-6.png?rev=3534890","caption":"Onboarding wizard \u2014 first-activation 4-step flow that takes a merchant from \"just clicked Activate\" to \"first rate quoted\" in under three minutes."},{"src":"https:\/\/ps.w.org\/precision-live-rates-for-woocommerce\/assets\/screenshot-7.png?rev=3534890","caption":"Audit log \u2014 append-only record of state-changing admin actions (settings saves, box CRUD, service-filter changes, cache clears, ShipEngine connection tests). Filter by event type, paginate, export to CSV."}],"raw_content":"<!--section=description-->\n<p><strong>Precision Live Rates<\/strong> brings real, account-accurate UPS, USPS, FedEx, DHL, and Stamps.com prices into WooCommerce's cart and checkout. No flat-rate guesswork, no aggregator markups bolted on top of the carrier rate, no rate drift between cart and checkout. The numbers your customers see are the same numbers you'd see on the carrier dashboard for the same parcel.<\/p>\n\n<p>Under the hood, the plugin packs each cart into the smallest viable parcel using a true 3D bin-packing algorithm (volume-then-SKU-then-product-id deterministic sort, ships-alone overrides honored, custom-packed dimensions for soft goods supported), POSTs the parcel to ShipEngine over HTTPS, dedupes the rate response by carrier+service, and caches the result on your server so identical carts don't trigger redundant API calls. The same <code>RateService::quote()<\/code> entry point feeds Classic Checkout, Blocks Checkout, and the WP-CLI <code>wp precision-rates test-rate<\/code> command \u2014 so cart, checkout, and your terminal all return byte-identical rates within the cache TTL.<\/p>\n\n<p>The diagnostic surface is built for real-world support load. The Rate Test admin screen captures every quote attempt's full request and response from ShipEngine into a 1-hour transient and surfaces it inline (collapsible, color-coded by HTTP status) so when a customer reports \"no shipping options,\" you can see exactly which carrier returned what. The Services screen auto-discovers every <code>carrier:service_code<\/code> flowing through the rate filter and lets you uncheck the ones you don't want shown. The Plugin Status panel on the Overview tab reports the running version, saved API key state, active carriers, cache TTL, and current markup at a glance \u2014 so verifying \"is the new code actually live with my settings\" is a glance, not an SSH dive.<\/p>\n\n<p>Privacy and compliance are first-class. The plugin transmits only postal codes, country codes, and parcel dimensions to ShipEngine \u2014 never customer name, email, IP, billing address, or order ID. Suggested privacy-policy boilerplate auto-registers with WP's Settings \u2192 Privacy editor on activation. Personal-data exporter and eraser hooks are wired so the WP Tools \u2192 Export\/Erase Personal Data flows recognize the plugin as compliant. EU\/UK merchants can flip on a Settings \u2192 Privacy toggle to render a \"Shipping rates calculated using ShipEngine \u2014 Privacy policy\" line under the cart and checkout shipping options.<\/p>\n\n<h4>Highlights<\/h4>\n\n<ul>\n<li><strong>Real carrier rates<\/strong> via ShipEngine's <code>\/v1\/rates<\/code> endpoint \u2014 UPS, USPS, FedEx, DHL Express, Stamps.com all behind a single API key. Or connect UPS \/ USPS directly with your own developer credentials.<\/li>\n<li><strong>True 3D bin-packing<\/strong> via the <code>dvdoug\/boxpacker<\/code> library. Define your box catalog under WooCommerce \u2192 Box catalog and items pack into the smallest viable box, ships-alone items respected.<\/li>\n<li><strong>Cart = checkout<\/strong>, byte-identical, within the cache TTL. Single quote pipeline shared by Classic Checkout, Blocks Checkout, and WP-CLI.<\/li>\n<li><strong>Encrypted credentials at rest<\/strong> via <code>sodium_crypto_secretbox<\/code>, derived per-install from <code>wp_salt('auth') . AUTH_KEY<\/code>. The plugin refuses to encrypt anything when AUTH_KEY is missing or matches the WP install placeholder.<\/li>\n<li><strong>Per-carrier markup<\/strong> to bridge negotiated rates to retail-equivalent prices. ShipEngine returns each carrier's negotiated rate (UPS often runs 30-50% below ups.com retail); set \"UPS markup %\" to 65-75 to display retail-equivalent prices without overcharging USPS shipments.<\/li>\n<li><strong>Rate Test diagnostic screen<\/strong> captures the raw request\/response of every quote \u2014 when checkout shows a price you didn't expect, this is the source of truth.<\/li>\n<li><strong>Services whitelist<\/strong> auto-discovered from carrier responses; uncheck what you don't want shown to customers.<\/li>\n<li><strong>GDPR-compliant out of the box.<\/strong> Privacy policy boilerplate, WP exporter\/eraser hooks, opt-in cart disclosure line.<\/li>\n<li><strong>i18n-ready<\/strong> \u2014 English (source), Spanish (es_ES), French (fr_FR) bundled. Other locales contribute via translate.wordpress.org once the plugin lists, or via pull request to the repo.<\/li>\n<li><strong>HPOS-required.<\/strong> No legacy order-table compatibility shims. Modern WC only.<\/li>\n<\/ul>\n\n<h4>Out of scope<\/h4>\n\n<p>The plugin is intentionally focused on rate calculation. It does <strong>not<\/strong> purchase shipping labels, generate manifests, schedule pickups, sync tracking webhooks back to order status, or integrate with multi-vendor marketplaces (Dokan, WCFM). For label printing and fulfillment, use ShipStation \/ ShipEngine's own dashboard or a separate WC label plugin.<\/p>\n\n<h3>Privacy &amp; data handling<\/h3>\n\n<p>This plugin transmits cart\/shipment data to a third-party rate aggregator (ShipEngine, https:\/\/www.shipengine.com\/) over HTTPS to calculate live carrier rates. Specifically, on each rate quote the following is sent:<\/p>\n\n<ul>\n<li>Origin postal code + country (and optionally street\/city\/state, as configured in plugin settings)<\/li>\n<li>Destination postal code + country (and street\/city\/state if the customer supplied them)<\/li>\n<li>Parcel weight and dimensions, computed from the cart contents<\/li>\n<\/ul>\n\n<p>The customer's name, email, phone, IP address, billing address, and order ID are NOT transmitted. Successful rate responses are cached on your server for a short, merchant-configurable duration (60\u20133600 seconds, default 60). The cache is keyed on parcel dimensions and origin\/destination ZIP only \u2014 it is not keyed on or attributable to any individual customer.<\/p>\n\n<p>EU\/UK merchants should turn on Settings \u2192 Privacy \u2192 \"Display privacy disclosure on cart\/checkout\" so a small \"Shipping rates calculated using ShipEngine \u2014 Privacy policy\" line renders under the cart and checkout shipping options. Suggested privacy-policy boilerplate is auto-registered with WP's Settings \u2192 Privacy \u2192 Policy guide editor on plugin activation.<\/p>\n\n<p>The plugin also registers no-op personal-data exporter and eraser hooks with WordPress so the Tools \u2192 Export Personal Data and Tools \u2192 Erase Personal Data flows recognise it as compliant \u2014 there is nothing per-customer to export or erase, but the hooks are present so the privacy admin's audit trail correctly accounts for the plugin.<\/p>\n\n<p>Full data-flow documentation, including the GDPR \/ CCPA \/ Quebec Law 25 compliance summary, is in PRIVACY.md at the repo root. ShipEngine's own data-handling practices are at https:\/\/auctane.com\/privacy-policy\/ (Auctane is ShipEngine's parent company).<\/p>\n\n<h3>External services<\/h3>\n\n<p>Precision Live Rates calls third-party shipping APIs to obtain live carrier rates. No external service is called until the merchant has explicitly enabled and configured at least one carrier source. The data sent is limited to what is needed to compute a shipping price \u2014 see the Privacy &amp; data handling section above for the exact payload.<\/p>\n\n<p><strong>ShipEngine<\/strong> (https:\/\/www.shipengine.com\/)\n* What it is: a rate-aggregation API that fronts UPS, USPS, FedEx, DHL Express, and Stamps.com.\n* What is sent: origin postal code, destination postal code + country, parcel weight + dimensions, and the configured ShipEngine carrier IDs. No customer name, email, IP, or order ID.\n* When it is called: on the cart and checkout pages when WooCommerce asks for shipping rates and the cached rate has expired (default 60 seconds).\n* Why: to compute live shipping prices that match what the carrier itself would charge.\n* Terms of service: https:\/\/www.shipengine.com\/terms-of-service\/\n* Privacy policy: https:\/\/auctane.com\/privacy-policy\/ (Auctane is ShipEngine's parent company)<\/p>\n\n<p><strong>UPS Developer APIs<\/strong> (optional, https:\/\/developer.ups.com\/)\n* What it is: UPS's official rate API.\n* What is sent: same shape as ShipEngine, plus the merchant's UPS account number.\n* When it is called: only when the merchant has explicitly enabled UPS direct under Settings \u2192 UPS direct and saved valid UPS developer credentials.\n* Why: lets merchants who have a direct UPS contract bypass ShipEngine and quote against their negotiated rate sheet.\n* Terms of service: https:\/\/www.ups.com\/upsdeveloperkit\/agreement\n* Privacy policy: https:\/\/www.ups.com\/us\/en\/help-center\/legal-terms-conditions\/privacy-notice.page<\/p>\n\n<p><strong>USPS Developer APIs<\/strong> (optional, https:\/\/developer.usps.com\/)\n* What it is: the United States Postal Service's official rate API.\n* What is sent: origin and destination postal codes, parcel weight + dimensions.\n* When it is called: only when the merchant has explicitly enabled USPS direct under Settings \u2192 USPS direct and saved valid USPS developer credentials.\n* Why: lets merchants who have a direct USPS account quote against USPS retail rates without ShipEngine in the path.\n* Terms of service: https:\/\/www.usps.com\/terms-conditions\/general.htm\n* Privacy policy: https:\/\/about.usps.com\/who\/legal\/privacy-policy\/welcome.htm<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Upload the plugin files to <code>\/wp-content\/plugins\/precision-live-rates\/<\/code>, or install via the WordPress Plugins screen. Activate.<\/li>\n<li>The first-activation onboarding wizard auto-launches: 4 steps from \"just activated\" to \"first rate quoted\" in under three minutes. Welcome \u2192 ShipEngine API key (with inline Test connection) \u2192 Origin address \u2192 Run a test quote.<\/li>\n<li>(Optional) Define your box catalog under WooCommerce \u2192 Precision Live Rates \u2192 Boxes. Without a box catalog, the cart aggregates into a single representative parcel; with a catalog, items 3D-bin-pack into the smallest viable box.<\/li>\n<li>(Optional) Tune per-carrier markups under Precision Live Rates \u2192 Settings \u2192 Markup. UPS typically benefits from a 65-75% markup to bridge negotiated \u2192 retail; USPS rates already match retail, so leave at 0.<\/li>\n<li>Verify the live cart shows expected rates. Use the Rate Test tab to simulate any cart against your live carrier configuration without leaving the admin.<\/li>\n<\/ol>\n\n<h4>Requirements<\/h4>\n\n<ul>\n<li>PHP 8.2 or higher<\/li>\n<li>WordPress 6.4 or higher<\/li>\n<li>WooCommerce 8.5 or higher with <strong>High-Performance Order Storage (HPOS) enabled<\/strong><\/li>\n<li><code>AUTH_KEY<\/code> defined in wp-config.php (rotate via https:\/\/api.wordpress.org\/secret-key\/1.1\/salt\/ if you've never customized it)<\/li>\n<li>A free or paid ShipEngine account, <strong>OR<\/strong> UPS\/USPS developer credentials. The onboarding wizard walks you through ShipEngine signup.<\/li>\n<\/ul>\n\n<!--section=faq-->\n<dl>\n<dt id=\"how%20do%20i%20get%20a%20shipengine%20api%20key%3F\"><h3>How do I get a ShipEngine API key?<\/h3><\/dt>\n<dd><p>Sign up at https:\/\/dashboard.shipengine.com\/ \u2014 the free sandbox tier returns synthetic rates that work end-to-end for testing. Once you're ready for production, the same dashboard issues <code>LIVE_\u2026<\/code> keys; connect at least one carrier (USPS via Stamps.com Connect is free and the easiest start) under ShipStation\/ShipEngine \u2192 Settings \u2192 Shipping \u2192 Carriers, then paste the key into Precision Live Rates \u2192 Settings \u2192 ShipEngine. The Test Connection button below the key field pings <code>\/v1\/carriers<\/code> and lists everything connected \u2014 use it to confirm the key authenticates before going live.<\/p><\/dd>\n<dt id=\"why%20are%20the%20ups%20rates%20i%20see%20lower%20than%20ups.com%20retail%3F\"><h3>Why are the UPS rates I see lower than ups.com retail?<\/h3><\/dt>\n<dd><p>ShipEngine returns each carrier's <em>account\/negotiated<\/em> rate. For UPS specifically, that's typically 30-50% below ups.com retail (UPS heavily discounts via aggregators to compete with USPS). To display retail-equivalent prices to customers, set the UPS markup % under Precision Live Rates \u2192 Settings \u2192 Markup. 65-75% bridges the gap for most accounts; check a few real shipments via the Rate Test tab to calibrate. USPS rates from ShipEngine already match retail \u2014 leave the USPS markup at 0.<\/p><\/dd>\n<dt id=\"can%20i%20use%20my%20own%20ups%20%2F%20usps%20developer%20account%20instead%20of%20shipengine%3F\"><h3>Can I use my own UPS \/ USPS developer account instead of ShipEngine?<\/h3><\/dt>\n<dd><p>Yes. Under Settings \u2192 UPS direct or USPS direct, paste your client ID + client secret. The plugin uses OAuth 2.0 client-credentials flows for both carriers. Sandbox and production toggle with a single checkbox. You can run UPS direct + USPS direct + ShipEngine simultaneously \u2014 rates from all three sources merge into a single deduped list at checkout.<\/p><\/dd>\n<dt id=\"how%20do%20i%20hide%20a%20shipping%20service%20from%20customers%3F\"><h3>How do I hide a shipping service from customers?<\/h3><\/dt>\n<dd><p>Trigger at least one rate quote (open the cart with a shippable address). Then visit Precision Live Rates \u2192 Services. Every <code>carrier:service_code<\/code> the plugin has seen is listed as a checkbox. Uncheck what you don't want, save. The change applies to the very next cart view \u2014 the plugin auto-flushes WC's shipping cache on save. If a service still shows up after saving, the cause is almost always a downstream cache (Varnish, Breeze, browser, CDN) serving a stale checkout page; the diagnostic count at the top of the Services screen tells you whether the save itself persisted.<\/p><\/dd>\n<dt id=\"what%20does%20%22combine%20parcels%22%20do%3F\"><h3>What does \"Combine parcels\" do?<\/h3><\/dt>\n<dd><p>Default on. When no box catalog is configured, the plugin can either ship each cart line as its own parcel (carriers bill each one \u2014 4 mugs = 4 UPS labels = 4\u00d7 the cost), or aggregate the cart into one representative parcel by stacking items along their smallest dimension. The default \"combine\" behavior is what most small shops want; toggle off under Settings \u2192 Packing if you genuinely need strict per-item billing. Once you configure a box catalog under Precision Live Rates \u2192 Boxes, items pack into real boxes regardless of this setting.<\/p><\/dd>\n<dt id=\"why%20is%20the%20cart%20still%20showing%20old%20rates%20after%20i%20changed%20something%3F\"><h3>Why is the cart still showing old rates after I changed something?<\/h3><\/dt>\n<dd><p>A few possibilities. (1) The plugin's own rate cache. Default TTL is 60 seconds; click \"Clear cached rates now\" on Overview \u2192 Quick actions to bust it immediately. (2) WC's shipping transient. Auto-flushed on every settings save, but if you saved via raw <code>update_option()<\/code> the auto-flush didn't fire \u2014 clear from Overview. (3) Editing a product's weight\/dimensions\/shipping class auto-invalidates the rate cache, so 0.2.2+ shouldn't have this issue from product edits. (4) Downstream cache (Cloudways Varnish, Breeze, browser, CDN) serving stale checkout HTML. The Services tab's diagnostic count distinguishes \"save didn't persist\" from \"downstream cache is stale.\"<\/p><\/dd>\n<dt id=\"does%20it%20support%20international%20shipping%3F\"><h3>Does it support international shipping?<\/h3><\/dt>\n<dd><p>It returns whatever the carrier returns for international destinations. The plugin's address-fallback logic currently optimizes for US ZIPs (auto-derives state from ZIP when the customer leaves it blank); other countries pass through. There is no separate customs declaration workflow yet \u2014 declared values and dimensions pass through to the carrier; carriers handle customs ingestion. Canadian and UK postal-code \u2192 province\/region inference is on the roadmap (BACKLOG E4).<\/p><\/dd>\n<dt id=\"where%20do%20i%20report%20bugs%20or%20request%20features%3F\"><h3>Where do I report bugs or request features?<\/h3><\/dt>\n<dd><p>GitHub issues: https:\/\/github.com\/sulemanshahjahan\/precision-live-rates-for-wooCommerce\/issues. Please include WordPress version, WooCommerce version, PHP version, plugin version, and (for rate-related issues) the relevant <code>&lt;details&gt;<\/code> block from Precision Live Rates \u2192 Rate test \u2192 Raw ShipEngine I\/O. The Logs tab also captures debug output when \"Verbose debug logging\" is enabled in Settings \u2192 Cache &amp; diagnostics \u2014 the most recent entries are usually the most relevant.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>0.2.39<\/h4>\n\n<ul>\n<li>WP.org reviewer round 3. <code>OnboardingWizard::renderField()<\/code> refactored to take typed <code>bool $required<\/code> and <code>?int $maxLength<\/code> parameters instead of an opaque <code>$extraAttrs<\/code> HTML-fragment string. Every dynamic value is now individually <code>esc_attr()<\/code>-escaped at the echo site, eliminating the <code>WordPress.Security.EscapeOutput.OutputNotEscaped<\/code> warning without resorting to a phpcs:ignore. Fixed two more 404 URLs in the External services + Privacy sections: ShipEngine terms now points to <code>https:\/\/www.shipengine.com\/terms-of-service\/<\/code> and the privacy policy to <code>https:\/\/auctane.com\/privacy-policy\/<\/code> (ShipEngine's parent company).<\/li>\n<\/ul>\n\n<h4>0.2.38<\/h4>\n\n<ul>\n<li>Hotfix for the admin-page styling regression introduced in 0.2.37: the CSS enqueue's <code>strpos($hookSuffix, ...)<\/code> check was matching against the text domain string instead of the admin menu slug, so the <code>precision-live-rates-admin<\/code> stylesheet never enqueued on a fresh install. Pinned the check to <code>AdminScreen::PAGE_SLUG<\/code> so it stays in sync with the menu slug regardless of what the text domain is renamed to.<\/li>\n<\/ul>\n\n<h4>0.2.37<\/h4>\n\n<ul>\n<li>Text domain now matches the WP.org-assigned plugin slug. Renamed from <code>precision-live-rates<\/code> to <code>precision-live-rates-for-woocommerce<\/code> across every <code>__()<\/code>, <code>_e()<\/code>, <code>esc_html__()<\/code>, etc. call (251 sites), the plugin header, the <code>Plugin::TEXT_DOMAIN<\/code> constant, the privacy exporter\/eraser slug, the WC Blocks integration name, the <code>phpcs.xml<\/code> configured text domain, and the language file names. Existing translations on translate.wordpress.org will now resolve correctly once the plugin is published. The admin menu slug (<code>?page=precision-live-rates<\/code>), CSS class prefixes, option\/transient keys, and hook prefixes are unchanged.<\/li>\n<\/ul>\n\n<h4>0.2.36<\/h4>\n\n<ul>\n<li>WP.org reviewer remediation round 2. <code>dvdoug\/boxpacker<\/code> upgraded from 3.12.1 to 4.1.1 (<code>InfalliblePacker<\/code> \u2192 <code>Packer::throwOnUnpackableItem(false)<\/code>, <code>getKeepFlat()<\/code> \u2192 <code>getAllowedRotation()<\/code>). Minimum PHP bumped 8.1 \u2192 8.2 to match the new boxpacker requirement. Vendor dev artifacts (<code>*.feature<\/code>, <code>*.py<\/code>, <code>*.ps1<\/code>, <code>vendor\/dvdoug\/boxpacker\/docs\/<\/code>, <code>vendor\/dvdoug\/boxpacker\/features\/<\/code>) now stripped from the submission zip via the build script's extension + path excludes. <code>BoxCatalogScreen::carriersField()<\/code> now runs each POSTed <code>allowed_carriers<\/code> entry through <code>sanitize_key()<\/code> before the value reaches <code>update_option()<\/code>. Fixed two USPS URLs in the External services section that returned 404.<\/li>\n<\/ul>\n\n<h4>0.2.35<\/h4>\n\n<ul>\n<li>WP.org reviewer remediation. Removed all premium-tier license \/ auto-update infrastructure references from shipped code (no License tab, no <code>registerLicensing()<\/code> method, no premium-tier mentions in the readme) so the plugin is fully GPL-compliant per Guideline 5. Renamed the PHP namespace from the generic <code>Acme\\PrecisionRates<\/code> to a project-specific <code>PrecisionLiveRates<\/code> per the prefix-uniqueness guideline. Tightened nonce handling in the SettingsPage and BoxCatalogScreen guard methods \u2014 <code>$_POST['_wpnonce']<\/code> now flows through <code>sanitize_text_field()<\/code> before <code>wp_verify_nonce()<\/code>. Removed the comparative-marketing paragraph from the description per directory-content rules. Added a <code>Requires Plugins: woocommerce<\/code> header. Replaced broken GitHub URLs in the plugin header. Expanded the External services section with explicit data-flow, ToS, and privacy-policy links for ShipEngine, UPS, and USPS.<\/li>\n<\/ul>\n\n<h4>0.2.34<\/h4>\n\n<ul>\n<li>WP.org Plugin Check round 3 \u2014 final cleanup pass. Plugin slug renamed from <code>wc-precision-rates<\/code> to <code>precision-live-rates<\/code> to clear the <code>trademarked_term<\/code> reviewer warning (<code>wc<\/code> is reserved for WooCommerce trademark protection). Bulk rename touches text domain, hook prefixes (<code>precision_live_rates_*<\/code>), constants (<code>PRECISION_LIVE_RATES_FILE<\/code> \/ <code>_DIR<\/code>), CSS asset handles, form-field prefixes (<code>plr_*<\/code>), and the plugin entry filename (<code>precision-live-rates.php<\/code>). The three remaining AuditLog SQL warnings (<code>WordPress.DB.PreparedSQLPlaceholders.ReplacementsWrongNumber<\/code>, <code>UnfinishedPrepare<\/code>, and the <code>$wpdb-&gt;insert()<\/code> <code>DirectQuery<\/code> warning) are now suppressed with the correct phpcs rule names \u2014 the previous phpcs:disable bands had <code>WordPress.DB.PreparedSQL.NotPrepared<\/code> listed, which is a different sniff than the <code>PreparedSQLPlaceholders.*<\/code> family that Plugin Check actually flags. Result: zero Plugin Check errors, zero warnings.<\/li>\n<\/ul>\n\n<h4>0.2.33<\/h4>\n\n<ul>\n<li>Plugin Check round 2 \u2014 moved the auto-update-bridge code out of the WP.org-bundled tree so the forbidden <code>pre_set_site_transient_update_plugins<\/code> token no longer appears in any shipped file. Excluded <code>WP-ORG-SUBMISSION.md<\/code> and any root <code>*.md<\/code> from the submission build. Removed the redundant <code>load_plugin_textdomain()<\/code> call (WP 4.6+'s just-in-time loader handles this). Migrated the AuditLog INSERT to <code>$wpdb-&gt;insert()<\/code> to clear <code>UnescapedDBParameter<\/code> warnings.<\/li>\n<\/ul>\n\n<h4>0.2.32<\/h4>\n\n<ul>\n<li>WP.org Plugin Check remediation pass. ABSPATH guards added to every PHP file under src\/; 20 throw-site interpolated values wrapped in esc_html() or annotated as chained-Exception; <code>Tested up to:<\/code> bumped 6.6 \u2192 6.9; readme tags trimmed 12 \u2192 5; short description trimmed to 121 chars; .gitkeep files excluded from the build script; composer.json now ships alongside vendor\/; $_SERVER['REMOTE_ADDR'] now flows through wp_unslash + sanitize_text_field; AuditLog SQL strings inlined into $wpdb-&gt;prepare() to clear false-positive UnescapedDBParameter warnings; TransientStorage prefix-DELETE warnings annotated.<\/li>\n<\/ul>\n\n<h4>0.2.31<\/h4>\n\n<ul>\n<li>Internal infrastructure work. No user-facing changes.<\/li>\n<\/ul>\n\n<h4>0.2.30<\/h4>\n\n<ul>\n<li>Customer-facing polish (BACKLOG E5). Three cart\/checkout enhancements: (1) delivery-date badges \u2014 small \"Arrives Wed, May 6\" labels appended to each shipping option, with relative phrasing for today\/tomorrow; (2) carrier logos \u2014 small inline-SVG marks (UPS, USPS, FedEx, DHL, Stamps.com) prepended to each rate label using carrier-brand colours but generic text marks (no trademark issues); (3) free-shipping threshold \u2014 flips the cheapest rate to FREE once the cart subtotal exceeds the configured value. New Settings \u2192 Customer-facing polish section with three toggles (delivery dates ON, carrier logos ON, threshold cents 0 = disabled). New <code>WooCommerce\\CustomerPolish<\/code> class with 14-test coverage.<\/li>\n<\/ul>\n\n<h4>0.2.29<\/h4>\n\n<ul>\n<li>Audit log (BACKLOG E8). New <code>Audit\\AuditLog<\/code> class + custom DB table records every state-changing admin action: settings saves, box CRUD, service-filter changes, cache clears, ShipEngine connection tests. New \"Audit log\" tab on the AdminScreen renders the most recent 100 entries with filter-by-event-type + paginated history; CSV export available. 30-day retention via daily cron (<code>precision_live_rates_audit_prune<\/code>); the cron event + retention window are filterable. Schema bootstraps idempotently via <code>dbDelta()<\/code> on <code>admin_init<\/code> so first-time installs see the table appear without an explicit activation hook. 10-test <code>AuditLogTest<\/code> + new <code>InMemoryWpdb<\/code> test double covering insert \/ SELECT \/ count \/ pagination \/ prune \/ CSV \/ event-slug stability.<\/li>\n<\/ul>\n\n<h4>0.2.28<\/h4>\n\n<ul>\n<li>International ZIP \/ postal-code coverage (BACKLOG E4). New <code>Support\\AddressInference<\/code> free function class extracted from the ShipEngine mapper: <code>stateFromPostalCode($postal, $country)<\/code> dispatches by ISO country code to US (50 states + DC + PR), Canada (10 provinces + 3 territories via the leading postal-code letter), or GB \/ UK (ENG \/ SCT \/ WLS \/ NIR via the postcode area prefix). Other countries pass through with empty state \u2014 ShipEngine doesn't strictly require it for non-US\/CA shipments. <code>ShipEngineRateMapper::buildAddress()<\/code> now uses the new helper for any country with no user-supplied state, so a Toronto M5V address with state blank produces <code>state_province: ON<\/code> in the ShipEngine payload, an Edinburgh EH1 address produces <code>SCT<\/code>, etc. 49-test parametric <code>AddressInferenceTest<\/code> covers ~20 Canadian postal-code prefixes, 16 UK postcode areas, and the dispatch-by-country surface.<\/li>\n<\/ul>\n\n<h4>0.2.27<\/h4>\n\n<ul>\n<li>WordPress.org submission prep. Plugin header URIs and Author updated from placeholders to the real values; readme.txt Contributors set to <code>sulemanshahjahan<\/code>; Description string in the plugin header updated to reflect the actual ShipEngine\/UPS\/USPS\/FedEx\/DHL surface; Tested up to bumped to 6.6. Static pre-flight scan against plugin-check expectations: zero hits for eval\/exec\/system\/shell_exec\/passthru\/proc_open, zero <code>sslverify=&gt;false<\/code>, zero <code>unserialize<\/code> of HTTP bodies, zero translation calls without text domain, all <code>__()\/_e()\/etc.<\/code> calls use the static <code>precision-live-rates<\/code> text domain. New <code>composer ci<\/code> script bundles <code>lint + stan + test + probe-mo<\/code> for one-command pre-submission verification.<\/li>\n<\/ul>\n\n<h4>0.2.26<\/h4>\n\n<ul>\n<li>readme.txt polish for WP.org review (BACKLOG E7 partial). 4-paragraph description with concrete selling points; removed stale \"no aggregators\" non-goal that contradicted the ShipEngine integration; expanded FAQ to 8 questions covering ShipEngine signup, UPS rate negotiation, UPS\/USPS direct, service hiding, combine_parcels, cache invalidation, international shipping, bug reports; new Screenshots block referencing 6 PNGs in \/assets\/ (placeholder until live captures land); README.md rewritten for the developer\/contributor audience with an architecture skim and the prod-vendor classmap dance documented prominently. Trimmed in-readme changelog to the most recent five releases \u2014 full history stays in CHANGELOG.md.<\/li>\n<\/ul>\n\n<h4>0.2.25<\/h4>\n\n<ul>\n<li>Privacy notice + GDPR consent (BACKLOG E6). New <code>Admin\\PrivacyNotice<\/code> class wires three things: (1) a suggested privacy-policy boilerplate auto-registered into WP Settings \u2192 Privacy \u2192 Policy guide editor, naming ShipEngine explicitly and enumerating exactly what is and isn't transmitted; (2) WordPress personal-data exporter + eraser hooks that report the plugin as compliant (the cache is keyed on parcel dimensions, not customer identity, so there's nothing to export or erase); (3) a merchant-controlled toggle (Settings \u2192 Privacy) that, when enabled, renders a small \"Shipping rates calculated using ShipEngine \u2014 Privacy policy\" line under the cart and checkout shipping options. Default off; EU\/UK merchants should turn it on. New <code>PRIVACY.md<\/code> documents the full data flow, retention windows, and compliance posture against GDPR \/ CCPA \/ Quebec Law 25.<\/li>\n<\/ul>\n\n<h4>0.2.24<\/h4>\n\n<ul>\n<li>i18n bundle (BACKLOG E3). Plugin is now fully translatable: <code>load_plugin_textdomain<\/code> wired on <code>plugins_loaded<\/code>, <code>.pot<\/code> regenerated against the live source (192 strings), and Spanish (es_ES) and French (fr_FR) translations bundled. Set the WordPress site language to Espa\u00f1ol (Espa\u00f1a) or Fran\u00e7ais (France) to see the AdminScreen tabs, onboarding wizard, settings, and Rate Test screen render in the chosen locale. New <code>CONTRIBUTING.md<\/code> documents the translation contribution flow.<\/li>\n<\/ul>\n\n<h4>0.2.23<\/h4>\n\n<ul>\n<li>Onboarding wizard fix: Step 2 (origin address) now redirects forward to the test-rate step on a successful save instead of re-rendering the same screen with a \"saved\" notice. The \"Save &amp; continue\" button label now matches what the button actually does.<\/li>\n<\/ul>\n\n<h4>0.2.22<\/h4>\n\n<ul>\n<li>First-activation onboarding wizard (BACKLOG E2). Replaces the cold settings-tab landing with a 4-step flow that takes a merchant from \"just clicked Activate\" to \"first rate quoted\" in under three minutes: welcome \u2192 ShipEngine API key (with inline Test connection) \u2192 origin address \u2192 run a test quote \u2192 finish. Skip-out link on every step; \"Re-run onboarding\" button under the Overview tab.<\/li>\n<\/ul>\n\n<h4>0.2.21<\/h4>\n\n<ul>\n<li>Test suite restoration (BACKLOG E1). 315 tests \u2192 389 tests, all green; phpstan level 8 and phpcs both clean. Two genuine bugs fixed along the way: <code>usStateFromZip()<\/code> mislabelled MA ZIPs (010xx-027xx) as Puerto Rico and didn't recognise RI (028xx-029xx); and the cache-clear admin-post handler was crashing because the <code>$tabUrl<\/code> closure variable wasn't imported.<\/li>\n<\/ul>\n\n<p>For the full per-release history including 0.1.0 through 0.2.20, see CHANGELOG.md in the repo.<\/p>","raw_excerpt":"Live UPS, USPS, FedEx, DHL, Stamps.com rates via ShipEngine. Deterministic 3D bin-packing. Cart=checkout, byte-identical.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/308942","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=308942"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/sulemanshahjahan"}],"wp:attachment":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=308942"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=308942"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=308942"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=308942"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=308942"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=308942"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}