DEV Community

Rojo
Rojo Subscriber

Posted on • Originally published at packagepr.com

Building a Shopify App That Actually Ships to Puerto Rico (Tutorial)

If you're building a Shopify store or app, there's a good chance your shipping configuration silently blocks 3.2 million potential customers in Puerto Rico.

Here's how to fix it — and a real example of what breaks.

The Default Shopify Problem

When you set up Shopify shipping, the default "Domestic" zone includes only the 50 US states. Puerto Rico gets lumped into... nothing. Or worse, "Rest of World."

This means:

  • PR customers see inflated "international" shipping rates
  • Some checkout flows reject PR addresses entirely
  • You lose sales you never knew you were missing

Step 1: Fix Your Shipping Zones

In Shopify Admin → Settings → Shipping:

  1. Edit your "Domestic" shipping zone
  2. Click "Edit zone"
  3. Search for "Puerto Rico" and add it
  4. Also add: Guam, US Virgin Islands, American Samoa, Northern Mariana Islands
// Shopify API equivalent
{
  "zone": {
    "name": "Domestic",
    "countries": [
      { "code": "US", "provinces": [] },
      { "code": "PR" },
      { "code": "GU" },
      { "code": "VI" }
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

Step 2: Configure Carrier Rates

For calculated shipping rates, make sure your carrier accounts handle PR:

// carrier-service callback
app.post('/shipping-rates', (req, res) => {
  const { destination } = req.body.rate;

  // PR zip codes: 00600-00988
  const isPuertoRico = destination.province_code === 'PR' 
    || (destination.zip && /^00[6-9]/.test(destination.zip));

  if (isPuertoRico) {
    // Use USPS rates - cheapest and most reliable for PR
    return res.json({ rates: getUSPSRates(destination) });
  }

  return res.json({ rates: getStandardRates(destination) });
});
Enter fullscreen mode Exit fullscreen mode

Pro tip: USPS Priority Mail treats PR the same as domestic. UPS and FedEx add surcharges. Default to USPS for PR orders.

Step 3: Test Your Checkout

Test addresses to use:

Zip City Use Case
00901 San Juan Metro area
00959 Bayamón Suburb
00680 Mayagüez West coast
00725 Caguas Mountain region

If any of these fail at checkout, you have a bug.

Step 4: Handle Tax Correctly

Puerto Rico has its own sales tax structure (IVU - Impuesto sobre Ventas y Uso at 11.5%). Don't charge mainland state tax to PR addresses:

function getTaxRate(address) {
  if (address.province_code === 'PR') {
    return 0.115; // IVU rate
  }
  return getStateTaxRate(address.state);
}
Enter fullscreen mode Exit fullscreen mode

The Business Case

  • 3.2 million potential customers in PR
  • Higher average order values (limited local retail options = more online shopping)
  • PR residents spend an estimated $5.5 billion on online shopping annually
  • Services like PackagePR exist specifically because retailers don't serve PR properly — that's demand waiting to be captured

Real-World Example

I helped configure a mid-size Shopify store that was unknowingly blocking PR. After adding PR to domestic shipping:

  • +47 orders in the first month from PR addresses
  • $3,200 in previously lost revenue
  • Zero increase in returns or shipping issues

Resources


Don't leave money on the table. Add those 5 territory codes.

Top comments (0)