How to Validate Adobe Commerce (Magento 2) Shipping Addresses with the Google Address Validation API
Check every new Adobe Commerce (Magento 2) order's shipping address against the Google Address Validation API, and hold orders whose address needs fixing before they reach the warehouse.
What This Integration Does
You can validate Magento 2 addresses without installing a checkout extension: a Spojit workflow reads new orders through the Adobe Commerce REST API, sends each shipping address to Google's Address Validation API, and acts on Google's verdict. Orders with a deliverable address carry on as normal. Orders with a missing unit number, a wrong postcode or a street Google cannot find get a private order comment explaining the problem and are put on hold, so nobody prints a label for a parcel that will come back. Because the check runs on the server after the order is placed, it works the same for the Luma checkout, a one-page checkout extension, a PWA or a headless storefront, and it never slows the checkout down.
The workflow runs on a schedule, every 15 minutes by default. Each run fetches orders created since the previous run, validates them one at a time, and leaves a record on the order itself (a comment, and a hold where needed). Re-running is safe: the workflow skips orders that already carry its comment, so an overlapping window never validates the same order twice.
Prerequisites
- An Adobe Commerce (REST) connection in Spojit using an integration access token with access to Sales (orders, comments, hold).
- A Google Cloud project with the Address Validation API enabled and billing turned on, plus an API key. Restrict the key to the Address Validation API in APIs & Services -> Credentials.
- Google's coverage list for your shipping countries. The API supports many regions but not all, and the depth of checking varies by country; check Google's coverage page before relying on it for a market.
- Optional: a Slack connection for a daily summary of held orders.
Step 1: Schedule Trigger
Add a Trigger node and set its type to Schedule. Use */15 * * * * with your store's timezone (for example Australia/Sydney). Fifteen minutes is quick enough to catch an order before the warehouse picks it and cheap enough to stay well inside Google's quotas.
Step 2: List New Orders
Add a Connector node on the Adobe Commerce REST connector in Direct Mode and pick the list-orders tool. Set:
status:pending(orprocessing, if payment capture moves orders straight on).createdAfter: a time slightly earlier than the last run, inYYYY-MM-DD HH:MM:SS. Use the Date & Time connector'ssubtracttool on the trigger time to subtract 20 minutes, thenformatit. The five minutes of overlap mean no order falls between two runs.pageSize:100.
Set the Output Variable to orders. Each order includes extension_attributes.shipping_assignments[0].shipping.address, which holds the shipping address with street (an array of lines), city, region, postcode and country_id.
Step 3: Loop Over Each Order and Build the Request
Add a Loop node in ForEach mode over {{ orders.data.items }}, with the item variable order. Set On iteration error to Continue with the next item so one bad address never blocks the rest of the batch.
Inside the loop, add a Transform node in Structured mode that builds Google's request body. Name its output gav_request:
{
"address": {
"regionCode": "{{ order.extension_attributes.shipping_assignments.0.shipping.address.country_id }}",
"addressLines": {{ order.extension_attributes.shipping_assignments.0.shipping.address.street }},
"locality": "{{ order.extension_attributes.shipping_assignments.0.shipping.address.city }}",
"administrativeArea": "{{ order.extension_attributes.shipping_assignments.0.shipping.address.region }}",
"postalCode": "{{ order.extension_attributes.shipping_assignments.0.shipping.address.postcode }}"
}
}
Magento stores the street as an array, which maps straight onto Google's addressLines. Magento's country_id is already a two-letter code, which is what regionCode expects.
Step 4: Call the Google Address Validation API
Add a Connector node on the HTTP Requests connector and pick http-post. Set:
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. Google's answer is in {{ validation.data.result }}. The part to act on is verdict:
verdict.possibleNextAction: Google's own recommendation, one ofACCEPT,CONFIRM,CONFIRM_ADD_SUBPREMISESorFIX. This field is marked preview by Google, so treat it as a strong hint rather than a contract.verdict.addressComplete:falsewhen a component is missing, unresolved or unexpected.verdict.validationGranularity: how precisely the address was matched, such asPREMISEorSUB_PREMISEfor a real building, orROUTEwhen only the street was found.
Google also returns address.formattedAddress, the corrected version, which is useful in the order comment.
Step 5: Decide and Act on the Order
Add a Condition node that passes when {{ validation.data.result.verdict.possibleNextAction }} equals ACCEPT. On the true branch, do nothing (or add an "Address verified" comment if your team likes the audit trail).
On the false branch, add two Connector nodes on Adobe Commerce REST, both using the raw-rest-request tool:
- Add a private comment.
methodPOST,pathorders/{{ order.entity_id }}/comments,body:{ "statusHistory": { "comment": "Address check: {{ validation.data.result.verdict.possibleNextAction }}. Google suggests: {{ validation.data.result.address.formattedAddress }}", "is_customer_notified": 0, "is_visible_on_front": 0 } } - Put the order on hold.
methodPOST,pathorders/{{ order.entity_id }}/hold, no body.
Holding the order stops invoicing and shipping until someone releases it, which is exactly the safety net you want. Your customer service team fixes the address with the customer and clicks Unhold in the Magento admin.
Step 6: Optional Daily Summary
To give the team one list instead of scattered comments, add a second small workflow on a 0 9 * * * schedule that calls list-orders with status holded and posts the order numbers to a channel with the Slack connector's send-message tool.
Tips
- Treat CONFIRM differently from FIX. A
CONFIRMverdict usually means Google corrected something small, such as a postcode, that a person should glance at. If holding those orders is too strict for you, add a comment without the hold forCONFIRMand hold onlyFIXandCONFIRM_ADD_SUBPREMISES. - Apartments and units:
CONFIRM_ADD_SUBPREMISESmeans the building exists but it needs a unit or apartment number. These are the parcels that most often come back, so hold them. - United States orders: add
"enableUspsCass": truenext toaddressin the request to get USPS CASS standardisation. Google only recommends it for US and Puerto Rico addresses. - Agent Mode alternative: if you would rather write the rules in plain English ("hold anything a courier would struggle to deliver"), replace the Condition with a Connector node in Agent Mode and a Response Schema with
actionandreasonfields.
Common Pitfalls
- Billing: every call is billed by Google to your Cloud project. Validating each order once, as this workflow does, keeps the cost predictable; validating on every address edit can multiply it.
- Key in the workflow: the API key sits in the HTTP step's headers, so restrict it to the Address Validation API in Google Cloud and rotate it if a workflow export is ever shared.
- Virtual orders: downloadable and virtual products have no shipping assignment. Add a Condition before Step 3 that skips orders without
shipping_assignments, or the Transform renders empty fields. - Region names: Magento's
regionis the full name (for example "New South Wales"). Google accepts full names, but if you see weak matches, leaveadministrativeAreaout and let the postcode and locality do the work.
Testing
Place two test orders in a staging store: one to a real address and one with a deliberately wrong postcode or a missing unit number. Run the workflow manually and confirm the first stays pending with no hold and the second has the comment and is on hold. Then switch the schedule on.