How to Validate Shopify Shipping Addresses with the Google Address Validation API
Check each new Shopify order's shipping address with the Google Address Validation API the moment it is placed, and tag orders with a bad address so your team fixes them before fulfillment.
What This Integration Does
Shopify's checkout accepts addresses that look right but are not deliverable: a missing apartment number, a postcode that belongs to the next suburb, a street name typed from memory. This Spojit workflow catches them as each order arrives. A Shopify orders/create webhook starts the run, the shipping address goes to Google's Address Validation API, and orders Google flags get an address-check tag and an order note with Google's suggested correction. Your team filters the Orders page by that tag, contacts the customer, and fixes the address before anyone buys a label.
Each run handles one order, so a failure on one address never affects another. Shopify retries webhooks it could not deliver, and Spojit deduplicates on Shopify's X-Shopify-Webhook-Id header, so a retried delivery does not validate or tag the same order twice.
Prerequisites
- A Shopify connection in Spojit with the
read_ordersandwrite_ordersscopes. - A Shopify webhook signing connection (created from the trigger panel), using the webhook signing secret from Settings -> Notifications -> Webhooks in your Shopify admin.
- A Google Cloud project with the Address Validation API enabled, billing on, and an API key restricted to that API.
Step 1: Webhook Trigger
Add a Trigger node, set the type to Webhook, and pick your Shopify signing connection. Leave the response mode on Async: Shopify only needs a fast 2xx. Copy the webhook URL, then in Shopify go to Settings -> Notifications -> Webhooks, click Create webhook, choose the Order creation event and the JSON format, and paste the URL.
The order arrives as {{ input }}. The fields you need are under {{ input.shipping_address }}: address1, address2, city, province_code, zip and country_code.
Step 2: Skip Orders That Do Not Ship
Add a Condition node that continues only when {{ input.shipping_address }} is not empty. Gift cards, digital products and local pickup orders have no shipping address, and there is nothing to validate.
Step 3: Build the Google Request
Add a Transform node in Structured mode with the output variable gav_request:
{
"address": {
"regionCode": "{{ input.shipping_address.country_code }}",
"addressLines": ["{{ input.shipping_address.address1 }}", "{{ input.shipping_address.address2 }}"],
"locality": "{{ input.shipping_address.city }}",
"administrativeArea": "{{ input.shipping_address.province_code }}",
"postalCode": "{{ input.shipping_address.zip }}"
}
}
An empty address2 becomes an empty string, which Google ignores. Shopify's country_code is the two-letter code Google expects in regionCode.
Step 4: Call the Address Validation API
Add a Connector node on HTTP Requests with the http-post tool:
url:https://addressvalidation.googleapis.com/v1:validateAddressheaders:{ "Content-Type": "application/json", "X-Goog-Api-Key": "YOUR_API_KEY" }body:{{ gav_request }}
Name the output validation. Read the decision from {{ validation.data.result.verdict.possibleNextAction }}, which is ACCEPT, CONFIRM, CONFIRM_ADD_SUBPREMISES or FIX, and the corrected address from {{ validation.data.result.address.formattedAddress }}. Google marks possibleNextAction as a preview field, so if you need a second signal, also check verdict.addressComplete.
Step 5: Tag and Note the Order
Add a Condition node that passes when possibleNextAction is anything other than ACCEPT. On that branch, add a Connector node on Shopify with the update-order tool:
id:{{ input.id }}tags: the order's existing tags plusaddress-check. Shopify sends existing tags as one comma-separated string in{{ input.tags }}; split it with the Text Tools connector'ssplittool, then appendaddress-check.note:Address check ({{ validation.data.result.verdict.possibleNextAction }}). Google suggests: {{ validation.data.result.address.formattedAddress }}
In Shopify, save an Orders view filtered by the address-check tag so the team has one queue to work through.
Step 6: Optional Slack Alert
For stores that fulfil within the hour, add a Slack connector step with send-message on the same branch: "Order {{ input.name }} has an address problem: {{ validation.data.result.address.formattedAddress }}". Someone can contact the customer before the pick list prints.
Tips
- Hold fulfillment too: to stop the order being fulfilled until it is fixed, call Shopify's
fulfillmentOrderHoldmutation through theraw-graphqltool on the order's fulfillment order. Tagging alone relies on the team checking the queue. - Grade the verdicts:
CONFIRM_ADD_SUBPREMISES(a unit or apartment is missing) is the most common reason parcels come back. Treat it as seriously asFIX, and use a softer tag such asaddress-confirmfor plainCONFIRM. - US orders: add
"enableUspsCass": truebesideaddressfor USPS CASS standardisation; Google recommends it only for US and Puerto Rico addresses. - Customer email: once you trust the verdicts, send the customer a "please confirm your address" email with the Send Email node on the
FIXbranch.
Common Pitfalls
- Tags are replaced, not added:
update-ordersets the full tag list. Sending onlyaddress-checkwipes every other tag on the order, so always merge with the existing tags. - Edited addresses: this workflow checks the address at order creation. If customers can edit it afterwards, also subscribe the same workflow to the Order edit or Order update event and remove the tag when the verdict becomes
ACCEPT. - Billing per call: Google bills every validation. One call per order is cheap; firing on every order update can multiply it, so filter update events to address changes.
- Coverage: Google does not validate every country to the same depth. Check Google's coverage list and skip countries where the result is weak, rather than tagging every order from them.
Testing
With the workflow saved, place a test order (or use a development store) with a real address, then one with a wrong postcode. Check the run history: the first should end at the ACCEPT branch, and the second should have tagged the order and added the note. Then let real orders through.