Skip to content
All Posts
Migration Guide

Fix Magento USPS AC-15210: v3 REST Replacement

· 7 min read · By RevAddress · Migration Guide

If your Magento 2 store stopped showing USPS shipping rates in January 2026, you hit AC-15210. The built-in Magento_Usps module calls the USPS Web Tools XML API — which was retired on January 25, 2026. That API no longer exists. No patch will fix it because the entire transport layer needs to be replaced.

This guide walks through the drop-in fix: a new carrier module (RevAddress_USPSv3) that uses the USPS v3 REST API with OAuth, coexists peacefully with the disabled built-in module, and restores live rates plus protected managed tracking routes without touching core Magento code.

What AC-15210 actually is

Magento’s official bug tracker entry AC-15210 documents the breakage: Magento_Usps hardcodes requests to http://production.shippingapis.com/ShippingAPI.dll — the old USPS Web Tools XML endpoint. After January 25, 2026, that endpoint returns connection errors or empty responses depending on your server’s timeout configuration.

The symptoms in your store:

  • Shipping method section shows no USPS options at checkout
  • Magento error logs contain USPS: Not Valid Country or connection timeout errors
  • Order tracking links return 404 or empty pages
  • 429 errors appearing in logs if you attempted the API migration USPS announced (the v3 endpoint requires OAuth, not USERID)

The underlying problem: Magento_Usps was never updated to support OAuth 2.0 client credentials or the v3 REST endpoints. It still references Zend_Http_Client patterns from Magento 1 heritage code. Backporting a patch would require replacing the HTTP client, the authentication layer, the request serializer, the response parser, and the tracking implementation — at that point you have rewritten the module. Skip the patch. Replace the carrier.

Why a clean replacement beats patching

The built-in module’s carrier class (Magento\Usps\Model\Carrier) inherits from AbstractCarrier but overrides so much of the rate collection and tracking logic that any partial patch creates a maintenance burden across every Magento security release. You would own a forked core module indefinitely.

The cleaner path: disable Magento_Usps entirely and install a new independent carrier module under your own namespace. Magento’s carrier system is designed for this — AbstractCarrier is the only interface contract. Third-party carriers like UPS, FedEx, and DHL all work this way. The RevAddress carrier follows the same pattern.

Benefits of the replacement approach:

  • Zero modifications to Magento core or vendor/
  • Survives Magento security patches and version upgrades
  • Clean namespace (RevAddress_USPSv3) that won’t conflict with a future official fix
  • The old module stays registered (disabled, not removed), so historical order records that reference carrier code usps continue to render correctly in the admin

The RevAddress USPS v3 carrier module

The RevAddress_USPSv3 Magento module wraps the RevAddress USPS v3 API. It handles OAuth token acquisition, rate requests against /prices/v3/total-rates/search, and tracking against /tracking/v3/tracking/{number}. Your Magento instance never touches the USPS OAuth endpoints directly — RevAddress holds the USPS OAuth credentials and your Magento store authenticates to RevAddress with a standard API key.

This matters for two reasons. First, USPS OAuth client credentials are tied to a single business application registration — you cannot embed them safely in a Magento config that is potentially shared across staging and production environments. Second, RevAddress handles the USPS rate limits (the v3 API enforces per-endpoint caps) and returns cached or degraded responses rather than surfacing raw 429s to your checkout flow.

Installation

Three steps. No Composer package yet — copy the module directly.

Step 1: Copy the module files

Copy module to app/code
mkdir -p app/code/RevAddress/USPSv3
cp -r vendor/revaddress/magento-usps-v3/src/RevAddress/USPSv3/* app/code/RevAddress/USPSv3/

If you are pulling from the GitHub release directly:

Pull from GitHub release
cd /tmp
curl -sL https://github.com/revereveal/magento-usps-v3/archive/refs/tags/v1.0.0.tar.gz | tar xz
cp -r magento-usps-v3-1.0.0/src/RevAddress/USPSv3 /var/www/html/app/code/RevAddress/USPSv3

Step 2: Copy the shared HTTP client

Copy shared client library
mkdir -p app/code/RevAddress/Shared
cp -r vendor/revaddress/magento-usps-v3/src/RevAddress/Shared/* app/code/RevAddress/Shared/

Step 3: Enable, upgrade, and clean

Enable module and run setup
bin/magento module:enable RevAddress_Shared RevAddress_USPSv3
bin/magento setup:upgrade
bin/magento setup:di:compile
bin/magento cache:clean
bin/magento cache:flush

Verify the module is active:

Verify module status
bin/magento module:status RevAddress_USPSv3
# Expected: Module is enabled

Configuration

Navigate to Admin → Stores → Configuration → Sales → Shipping Methods. You will see a new USPS v3 (RevAddress) section.

FieldValue
EnabledYes
TitleUnited States Postal Service
RevAddress API KeyYour rv_live_... key from /pricing
Origin ZIP CodeYour warehouse or fulfillment ZIP
Allowed Mail ClassesPriority Mail, Priority Mail Express, Ground Advantage, etc.
Show Method if Not ApplicableNo
DebugNo (enable temporarily if rates are not appearing)

For label generation, you will also see BYOK (Bring Your Own Keys) fields. If you have your own USPS business account, enter your USPS OAuth Client ID and Secret here. RevAddress will use your credentials directly for label requests. Leave these blank to use the RevAddress shared label pool.

After saving, clear the config cache:

Clear config cache after saving
bin/magento cache:clean config

How rate collection works

The carrier implements Magento’s standard collectRates(RateRequest $request) contract. Here is the core flow:

Carrier rate collection — simplified
<?php
// app/code/RevAddress/USPSv3/Model/Carrier.php

namespace RevAddress\USPSv3\Model;

use Magento\Shipping\Model\Carrier\AbstractCarrier;
use Magento\Shipping\Model\Carrier\CarrierInterface;

class Carrier extends AbstractCarrier implements CarrierInterface
{
  protected string $_code = 'revaddress_usps';

  public function collectRates(RateRequest $request): ?Result
  {
      if (!$this->getConfigFlag('active')) {
          return null;
      }

      $payload = [
          'originZIPCode'      => $this->getConfigData('origin_zip'),
          'destinationZIPCode' => $request->getDestPostcode(),
          'weight'             => $this->normalizeWeight($request),
          'length'             => $request->getPackageLength(),
          'width'              => $request->getPackageWidth(),
          'height'             => $request->getPackageHeight(),
          'mailClasses'        => $this->getAllowedMailClasses(),
      ];

      $response = $this->client->post('/api/usps/rates', $payload);

      $result = $this->rateResultFactory->create();

      foreach ($response['rates'] as $rate) {
          $method = $this->rateMethodFactory->create();
          $method->setCarrier($this->_code);
          $method->setCarrierTitle($this->getConfigData('title'));
          $method->setMethod($rate['mailClass']);
          $method->setMethodTitle($rate['description']);
          $method->setPrice($rate['totalPrice'] / 100);
          $method->setCost($rate['totalPrice'] / 100);
          $result->append($method);
      }

      return $result;
  }
}

The client->post('/api/usps/rates') call hits the RevAddress API, which handles the USPS /prices/v3/total-rates/search integration. RevAddress normalizes the response, manages OAuth refresh, and enforces safe defaults if USPS returns a partial response (for example, when a mail class is unavailable for the requested dimensions).

Weight normalization converts Magento’s pound/ounce configuration into the gram values the v3 API expects.

Tracking integration

The carrier implements isTrackingAvailable() and getTracking(). Tracking requests route through RevAddress to the USPS /tracking/v3/tracking/{number} endpoint.

Tracking implementation
<?php
public function isTrackingAvailable(): bool
{
  return true;
}

public function getTracking(string|array $trackings): Result
{
  $result = $this->trackFactory->create();

  foreach ((array) $trackings as $number) {
      $response = $this->client->get("/api/usps/tracking/{$number}");

      $status = $this->trackStatusFactory->create();
      $status->setCarrier($this->_code);
      $status->setCarrierTitle($this->getConfigData('title'));
      $status->setTracking($number);
      $status->setTrackSummary($response['summary'] ?? '');

      if (!empty($response['events'])) {
          $status->setProgressdetail($this->formatEvents($response['events']));
      }

      $result->append($status);
  }

  return $result;
}

Tracking results appear in the standard Magento My Orders → Track Order flow with no template changes required. The carrier code revaddress_usps is what Magento stores on new orders created after the module is enabled.

Disabling the old Magento_Usps module

Disable — do not remove. Removing the module deletes the database schema entries that historical orders reference when rendering the carrier name in admin.

Disable the built-in USPS module
bin/magento module:disable Magento_Usps
bin/magento setup:upgrade
bin/magento cache:clean

Before running this, check whether you have orders that used the old usps carrier code:

Check for existing USPS orders in database
mysql -u magento -p magento -e \
"SELECT COUNT(*) as order_count FROM sales_order WHERE shipping_method LIKE 'usps_%';"

If that count is above zero, keep the module disabled (not removed). Magento will still render the carrier name for historical orders — it reads from sales_order.shipping_description which is a stored string, not a live carrier lookup. The module code itself is no longer called. You get clean separation: old orders display correctly, new orders go through revaddress_usps.

If the count is zero (fresh store or all orders shipped before USPS broke), you can remove the module entirely from vendor/ after disabling, but disabled is sufficient and safer.

Common issues

SymptomCauseFix
No rates at checkoutAPI key not saved or wrong environmentVerify key in config, clear cache, enable Debug mode, check var/log/shipping.log
Rates appear but are $0.00Weight not set on productsSet product weight in grams or check unit config under carrier settings
429 errors in logsRevAddress rate limit exceeded (unlikely on standard plans)Check your plan limits at /pricing; contact support if unexpected
Tracking shows “No information”Order created with old usps carrier code or USPS has not recognized the new item yetOld orders route to Magento_Usps — not fixable retroactively; new orders hit the v3 tracking route once USPS recognizes the parcel
Config not savingMagento config cacheRun bin/magento cache:clean config after every save
Module not found after enableDI compile not runRun bin/magento setup:di:compile
Carrier not appearing in adminWrong section — check Sales > Shipping Methods, not CarriersNavigate to Stores → Configuration → Sales → Shipping Methods

What you have after this fix

  • Live USPS rates at checkout via the v3 REST API
  • Priority Mail, Priority Mail Express, Ground Advantage, and all v3 mail classes
  • Protected tracking integration against the v3 tracking endpoint; event detail appears as USPS scan data becomes available
  • Label generation (with either RevAddress shared pool or your own USPS OAuth credentials via BYOK)
  • No modifications to Magento core — survives upgrades cleanly
  • Historical orders using the old usps carrier code continue to display correctly

The AC-15210 bug is a known upstream issue with no official Magento patch timeline. The replacement carrier approach is the most dependable path that Magento enterprise agencies have been deploying since February 2026.


Get started: Create a free RevAddress account — the free proof path lets you test rate requests and address validation first, then expand into protected managed tracking routes before you expose customer-facing shipment status.

Related reading:

Keep the free proof wedge first

USPS v3 developer toolkit. Free tier for validation and rates. Flat monthly pricing.

Validation, ZIP+4, and rates are the free proof path. Labels, tracking, BYOK, and pickup stay protected until the workflow and proof gates are actually ready.