lqt / loqate-integration
Performs address capture and data validation (email, phone number and address) using Loqate API.
Package info
github.com/loqate/loqate-magento
Language:JavaScript
Type:magento2-module
pkg:composer/lqt/loqate-integration
Requires
This package is auto-updated.
Last update: 2026-07-21 14:26:38 UTC
README
What is the Loqate API Integration?
Performs address capture and data validation (email, phone number and address) using Loqate API.
Download
Developing in this repo's devcontainer? You don't need any of the download steps below — the devcontainer already installs and symlinks your local working copy. See Using the local dev copy.
Download via composer
Request composer to fetch the published release from Packagist:
composer require lqt/loqate-integration
Manual Download
Download & copy the git content to app/code/Loqate/ApiIntegration.
Install
Please run the following commands after you download the module.
php bin/magento module:enable Loqate_ApiIntegration
php bin/magento setup:upgrade
php bin/magento setup:di:compile
Configuration Instructions
The configuration for the module is located under Stores -> Configuration -> Loqate.
Magento 2 DevContainer Setup
This repository includes a devcontainer for rapid Magento 2 extension development.
Quick Start
- Create a devcontainer.env: Before opening the devcontainer you will need to create a
devcontainer.envfile which you can copy fromdevcontainer.env.example. - Open in VS Code: Use the "Reopen in Container" command (requires the Remote - Containers extension).
- Wait for Setup: The devcontainer will build, install dependencies, and set up Magento 2 automatically.
- Access Magento:
- Storefront: http://localhost:8080
- Admin: http://localhost:8080/admin
- Default admin user:
admin/admin123
- Live Extension Development: The devcontainer runs your local working copy (
/workspace/loqate-magento), mirrored into the Magento instance. After editing the source, runsync-extension.shto apply the changes (see Using the local dev copy below).
Using the local dev copy
The devcontainer runs your local working copy (/workspace/loqate-magento) rather than the published Marketplace/Packagist release, so your edits are what Magento executes.
Why it's a copy, not a symlink
Magento cannot render templates (or read other view files) from a module whose real path is outside the Magento base dir. A Composer path repository on the same filesystem is installed as a symlink, and the symlinked module registers its real path (/workspace/loqate-magento, via registration.php's __DIR__) — which is outside /workspace/magento2. The result is an error at checkout / address forms:
Path "/workspace/loqate-magento/view/frontend/templates/config.phtml"
cannot be used with directory "/workspace/magento2/"
A bind mount would keep the files under the base dir and stay live-editable, but this container isn't privileged enough to bind-mount. So the extension is installed as a real copy under vendor/gbg-loqate/loqate-integration, and edits are re-applied with a sync script. setup-magento.sh wires this up:
-
A Composer path repository named
loqate-localis registered against the extension directory. -
The extension is required by its path-repo package name,
gbg-loqate/loqate-integration(thenamein this repo'scomposer.json), which registers the package + pulls dependencies:composer require gbg-loqate/loqate-integration:@dev
-
sync-extension.shthen replaces the symlink Composer created with a real copy of the source.
Important: do not require
lqt/loqate-integration— that is the published Packagist release and would install a fixed version intovendor/lqt/loqate-integration, ignoring your local changes. Only one of the two may be installed at a time: both register the same module name (Loqate_ApiIntegration), so having both present causes a "module already registered" error.
After editing the code — sync your changes
Run the sync script from anywhere in the container:
.devcontainer/sync-extension.sh # copy source + cache:flush (PHP body / template / JS edits) .devcontainer/sync-extension.sh --full # also setup:upgrade + di:compile (di.xml / config / plugins / schema)
Because it's a copy, your edits are not live — nothing changes in Magento until you run the sync script. (
composer install/update/reinstallwill re-create the symlink and reintroduce the template error; if that happens, just run the sync script again.)
Verify you're running the local copy:
cd /workspace/magento2 grep '"version"' vendor/gbg-loqate/loqate-integration/composer.json # your working-copy version ls -ld vendor/gbg-loqate/loqate-integration # a real directory, NOT a symlink bin/magento module:status Loqate_ApiIntegration # -> "Module is enabled"
Switching an already-built instance from the published copy to the local copy (e.g. if vendor/lqt/loqate-integration was installed first):
cd /workspace/magento2
composer config repositories.loqate-local path /workspace/loqate-magento
composer remove lqt/loqate-integration
composer require gbg-loqate/loqate-integration:@dev
.devcontainer/sync-extension.sh --full
Services
- PHP-FPM (8.4)
- Nginx
- MySQL 8
- Opensearch
- Redis
Notes
- The first startup may take several minutes (Magento install, Composer, DB setup).
- The extension is installed from the local
loqate-localComposer path repository as a real copy invendor/gbg-loqate/loqate-integration; re-apply source edits withsync-extension.sh(see Using the local dev copy). - To re-run setup, use
.devcontainer/setup-magento.shinside the container. - If you have any DNS issues, you will need to copy your Zscaler certificate into the PHP container - see the Zscaler workaround comment in the
Dockerfile.
Useful helpers
php -r '$e=include "app/etc/env.php"; $d=$e["db"]["connection"]["default"]; printf("mysql -h%s -u%s -p%s %s\n",$d["host"],$d["username"],$d["password"],$d["dbname"]);'Will extract the command to access mysql within the devcontainer, currently that command ismysql -hdb -umagento -pmagento magentobin/magento config:showwill list all of the config currently set in the instance, this can be set withbin/magento config:set <PATH> <VALUE>
Testing
Automated unit tests
Unit tests live under Test/Unit and run with Magento's unit test suite. From the Magento root of an instance that has the module installed:
# Module installed via composer: vendor/bin/phpunit -c dev/tests/unit/phpunit.xml.dist \ vendor/gbg-loqate/loqate-integration/Test/Unit # Module installed under app/code: vendor/bin/phpunit -c dev/tests/unit/phpunit.xml.dist \ app/code/Loqate/ApiIntegration/Test/Unit
Test/Unit/Helper/ValidatorTest.php covers the captured-address (Loqate lookup) bypass: array-street parsing, that a looked-up address is recognised across countries (e.g. UK province-name vs region, US CA vs California), case/whitespace tolerance, and the guards that a different or empty address is not bypassed.
Manual testing (checkout flow)
Prerequisites (Admin → Stores → Configuration → Loqate, or bin/magento config:set):
loqate_settings/settings/api_key— a valid Loqate API keyloqate_settings/address_settings/enable_checkout=1(verification enabled at checkout)- Capture/lookup enabled on checkout
- Optional: set strict thresholds under
loqate_settings/verify_threshold_settingsso a hand-typed address would be rejected, making the bypass behaviour obvious
Verify a looked-up address is accepted (the main regression):
- Go to checkout (guest or logged-in).
- Use the Loqate lookup and select a suggested address from the dropdown — do not hand-type it.
- Proceed through shipping / place order. The address should be accepted and checkout should proceed (the selected address bypasses re-verification).
Different-country checks (the bypass is locale-agnostic):
- US — lookup returns the state as a full name (e.g. California) while Magento stores the region as
CA; the address should still be accepted. - UK — lookup an address with no region; should be accepted.
Guard checks (verification is still active):
- Hand-type an invalid address without using the lookup → verification still fires and rejects it.
- Select a lookup address, then edit a field (e.g. the street) → it is re-verified, since it no longer matches the captured address.
Observe via logs — a bypassed (captured) address makes no verify API call, whereas a hand-typed one does:
tail -f var/log/loqate*.log
Deployment
Releasing a new version requires two separate deployments: one to the Adobe Marketplace and one via Composer. Before proceeding with either, update the version number in both composer.json and etc/module.xml to reflect the new release, then commit and push the change.
Note that the Git tag for the Composer release is created automatically when changes are merged to master — see the Composer section below.
Adobe Marketplace
- Create a zip of the whole repository. Ensure that
.devcontainer,.gitand.gitignoreare excluded, as the Magento malware scan does not allow them to be uploaded. The following command will produce a clean archive:zip -r loqate-integration.zip . -x "*.git*" -x "*.devcontainer*"
- Log in to your Adobe account at account.magento.com.
- Navigate to the extension versions page on the Adobe Commerce Developer Portal.
- Upload the zip archive.
- Adobe will automatically process and scan the submission. This can take up to 15 business days if a manual approval is required.
- If the scan fails, review the provided feedback, address the reported issues, and resubmit.
- If the scan passes, the extension will be published to the marketplace within the hour.
Composer
The Git tag for a Composer release is created automatically. When changes are merged to master, the auto-tag.yml GitHub Action analyses the commits since the previous tag and creates a new version tag based on Conventional Commits:
feat:commits → MINOR bump (e.g.v2.0.4→v2.1.0)fix:commits → PATCH bump (e.g.v2.0.4→v2.0.5)feat!:orBREAKING CHANGE:→ MAJOR bump (e.g.v2.0.4→v3.0.0)- Other types (
docs:,style:,refactor:, etc.) → no bump (no tag created)
If none of the commits since the previous tag are feat:, fix:, or a breaking change, no tag is created and no release is published — so commits like docs:, chore:, ci:, refactor:, etc. can be merged to master without cutting a release. When a release is cut, the workflow also publishes a GitHub release with an auto-generated changelog. Once the new tag is pushed, Composer will automatically detect it and make the release available on packagist.
To ensure a release is tagged correctly, make sure your commit messages follow the Conventional Commits format.