Skip to content
MyStoreKit
Fraud prevention

Catching address typos and PO boxes on Shopify: checkout rules that prevent delivery problems

Most delivery problems are invisible until you actually ship the order. A ZIP code with a digit missing. A typo in the address line. A destination parcel carriers won’t deliver to, like a PO box. All of these can be detected mechanically the moment they’re typed at checkout. There are too many orders to check each one by hand, and finding out after shipping is too late.

In this article, I’ll lay out how to build rules that stop address typos and PO box orders at Shopify’s checkout. I built Validify Checkout Guard, the app used here, so this comes from the person who made it. The idea is the same as fraud prevention and purchase quantity limits: check conditions before payment completes, and stop only the orders that trip them. Address problems get less attention than fraud because they’re less visible, but the damage piles up quietly.

What address problems actually cost

The reason address mistakes go unnoticed until delivery is that payment goes through anyway. You get paid, and the order stands. The problem only surfaces when the carrier’s system rejects the address, or the driver brings the package back. In other words, it shows up at the most expensive stage.

Here’s what the damage looks like.

First, reshipping costs. If a package comes back because of a bad address, the shipping cost is wasted both ways. The packaging has to be redone, and once you count the labor of reshipping, the cost per incident is not light. On thin-margin products, a few returns can eat a month’s profit. When a PO box turns out to be undeliverable, you either wait for the customer to pick the package up or wait for it to come back, and either way it takes time.

Second, support workload. A “where is my order” inquiry comes in, you look up the shipment, confirm the address, process the reshipment. None of that work generates revenue. Even when the typo is on the buyer’s side, the store pays the labor. If the response is slow, frustration grows on top.

Third, and hardest to see, the effect on reviews. If delivery runs a few days late because of a reshipment, the review says “slow shipping.” Even when the cause was a typo, the name in the review is the store’s. A low rating, once given, is hard to fix later.

What all of these have in common is that detection happens after shipping. So the right move is to pull detection earlier, to the moment the address is typed at checkout. The rest of this article is the concrete rules for that.

Checking the ZIP code format with a regex

The most common input mistake is a broken ZIP code format. A digit missing, letters mixed in, a stray space. These can all be stopped mechanically with a rule.

Every rule is written as criterion + operator + value. To enforce the US ZIP format, that’s these three:

  • Criterion: ZIP code
  • Operator: regex mismatch
  • Value: ^\d{5}(-\d{4})?$

This regex matches the US ZIP format (12345, or 12345-6789). When the entered ZIP code doesn’t match it, meaning it isn’t 5 digits, has extra characters, or contains letters, checkout stops. The stop happens before payment, so no payment processing fee or cancellation process ever occurs.

Regexes are evaluated case-insensitively and can be up to 200 characters long. A compile check runs when you save, so a mistyped pattern can’t leave a rule silently broken. There are 10 criteria that accept regexes, and ZIP code is one of them. City and address lines are available as criteria too, so you can place the same kind of validation on each part of the address in the form.

One caution. The regex above assumes the US format. If a store that also ships internationally applies this rule to every order unconditionally, it will block every foreign postal code (ones containing letters, ones with a different digit count). If you sell across borders, either add the shipping country as a condition so the rule only bites on US orders, or separate the judgment with the shipping country rules described later. Conditions stack with AND, so “shipping country is the United States” plus “ZIP code doesn’t match the format” is a buildable combination.

Detecting orders addressed to PO boxes

Orders addressed to a PO box are a particular problem for domestic parcels. UPS and FedEx don’t deliver to PO boxes, so the order only turns out to be undeliverable after you ship it. The package either lands at the post office that manages the box or gets carried back. Either way, the reshipment and the extra shipping are on the store.

PO box and forwarding service addresses are also used for reseller stock. If you don’t want people buying at consumer prices to resell, this is a condition you can’t ignore in the fraud prevention context either.

There’s a dedicated criterion for this. Set criterion “PO Box detection” + operator “is true” and that’s the whole rule. It detects the patterns PO BOX, P.O. BOX, POB, and post office box in address line 1 and address line 2, ignoring case. “po box” and “Po Box” both trip it. You don’t need to write your own regex word list; placing the criterion is enough.

If you want to stop general orders but keep exceptions for PO boxes agreed with a business, combine conditions. Stack it with AND/OR against, say, the “B2B checkout” criterion or a customer tag, and you get an arrangement where business customers aren’t affected. Other rules around B2B orders, like making a PO number required, are covered in the B2B PO number article.

Blocking regions you don’t ship to

A bigger unit of protection than address format is restricting the destination itself.

The “Shipping country” criterion is chosen from a picker of 249 countries. Combine it with the operator “is none of” and enumerate the countries you do ship to, and orders going somewhere you can’t ship are stopped up front. A domestic-only store gets by with a single condition: “shipping country is not equal to the United States.” Stopping a foreign address at checkout costs both sides far less friction than taking the order and declining it afterward. Addresses in countries you have no shipping contract for also clash with the ZIP format check, so in many cases blocking at the country level first is the sounder order.

To narrow things down within the country, the “State/province code” criterion works. If you want to exclude territories you can’t ship to, or keep certain states outside refrigerated delivery, list the codes and block with “is any of”. Shipping method name and shipping method type are criteria too, so “this shipping method doesn’t cover this region” is also a buildable condition. You can block in fine detail to match how you actually ship, within the limits of 25 conditions per rule and 25 rules per policy. The order that stays explainable later is to start wide (country) and add narrower units (state) as actual trouble shows up.

What this approach can’t do

Let me be honest about the limits here. This approach is focused on validating and blocking form input by format. It does nothing beyond that.

First, no address autocomplete from the ZIP code. Suggesting address candidates mid-entry or filling in the street number is the territory of address form apps. This app plays one role: validating the format of the address as entered, and stopping checkout when it trips a criterion. Autocomplete and validation are different jobs, and my view is that each staying single-function is more stable than one app carrying both.

Second, no verification that an address exists. Whether the written address actually exists, or whether the person really lives there, that kind of credit-style check isn’t performed. It’s strictly validation of conditions a rule can judge: is the format invalid, is it a PO box, is it outside your shipping area. The risk of address existence was scoped out of this app’s territory from the start.

Put the other way, being specialized keeps the behavior simple. It’s block-only; there’s no middle state like showing a warning or raising a flag. The design is fail-open, so even if the app errors, checkout itself doesn’t stop, and a malfunctioning rule never gets between a legitimate customer and their purchase. Stating what it can’t do up front is how you avoid disappointment after installing.

Messages and getting started

When a rule blocks, you can write the message that tells the shopper what’s wrong. Showing just “Invalid ZIP code” versus “Please enter your ZIP code as 12345 or 12345-6789” changes whether a legitimate customer can recover and finish the purchase. The trick is to write what tripped, and the next step. The same goes for PO box blocks: write that PO boxes can’t receive parcels and that swapping the address will let the purchase through, and legitimate customers fix the address and come back.

Messages support 36 languages and display in the shopper’s language. You can write up to 500 characters per message.

Getting started is a 7-day free trial. My recommendation is to place the two rules first, the ZIP format check and PO box detection, then spend the trial comparing them against your store’s order history: is anything over-blocked, is anything slipping through. It’s $5 a month, and the rules are stored inside your own store’s Shopify data. If setup gives you trouble, I answer support myself within 24 hours. You can check the app details here.