Lazada Store Management
This is the installation and configuration guide for Lazada Store Management, the module you downloaded from your ECOSIRE dashboard. Everything on this page describes the lazada_store_management module exactly as it ships today — the facts below were read out of the released build, not from a roadmap.
| Technical name | lazada_store_management |
| Odoo versions | 17.0, 18.0, 19.0 (Community or Enterprise) |
| Published version (what you download today) | 17.0 → 17.0.2.0.3, 18.0 → 18.0.2.0.2, 19.0 → 19.0.2.1.2. The 2.2.x notes below describe the next release, built and tested but not yet published |
| Price | $499 USD — one-time, per Odoo version |
| Odoo module licence | OPL-1 on 17.0, 18.0 and 19.0 |
| Licence key | Not required on any series — you install the ZIP and the module works |
| Category | Connector |
This module contains no licence client, no activation check and no execution block: you install the
ZIP and it works. Your rights are governed by the OPL-1 licence it ships under, and support and
updates follow your purchase.
Nothing else is downloaded alongside it and there is nothing to install first, on any series — the only archive you need is the connector itself.
Upgrading a database from an older build? Archives published before 17.0.2.1.0 / 18.0.2.1.0
declared a separate free helper module. The current builds do not, so you may remove that helper
afterwards unless another ECOSIRE module in the same database still uses it.
Each Odoo major version is a separate product: your purchase entitles you to the download for the Odoo version you bought, and a build for one major version does not install on another. Buy the version you actually run, and if you later upgrade Odoo you need the build for the new version.
Requirements
| Requirement | Detail |
|---|---|
| Odoo | 17.0, 18.0 or 19.0, Community or Enterprise. Self-hosted or Odoo.sh — Odoo Online (SaaS) cannot install third-party modules |
| Odoo apps | base, sale_management, stock, account, delivery, mail, web, product, contacts, mrp — Odoo installs any that are missing |
| ECOSIRE dependency | None on any series. The module installs on its own; there is no licence client to download |
| Python packages | requests |
| Platform account | A Lazada account with API access |
| Licence | Your purchase for this module and your Odoo version. No key is entered in Odoo |
mrp is required because the connector maps Lazada combo listings onto Odoo bills of materials.
Install the Python packages into the same interpreter that runs Odoo:
sudo -u odoo pip install requests
Installation
1. Download the ZIP for your Odoo version
Sign in at ecosire.com and open your dashboard downloads. You will only be offered the file matching your purchase's Odoo version — that is expected, see the warning above.
2. Extract into your addons path
unzip lazada_store_management_v19_*.zip -d /opt/odoo/addons/
ls /opt/odoo/addons/lazada_store_management/__manifest__.py # sanity check
The module must end up as a single top-level lazada_store_management/ directory with __manifest__.py directly inside it. If your ls check fails, the folder landed one level too deep or too shallow — move it so the path above resolves.
3. Restart Odoo and install
sudo systemctl restart odoo
- Go to Apps and click Update Apps List (developer mode must be on).
- Search for Lazada Store Management and click Install.
- Odoo pulls in the Odoo apps listed above automatically. There is no ECOSIRE module to install alongside it.
When the install finishes, a Lazada menu appears in the main Odoo app switcher.
Configuration
Connect to Lazada — step by step
This section was rewritten on 17 September 2026 and re-checked on 25 September 2026 from a fresh installation
of the Odoo 19 build current at that date (19.0.2.2.1) and from Lazada Open Platform's
own developer-console guides covering the seller role, application
creation, the parameters those applications carry, seller authorization and
its introduction, as they read on that date (last updated by Lazada between
5 March and 23 June 2026). It has two halves: what you do on Lazada Open
Platform, then what you do in Odoo.
Verified against Lazada's live API while preparing this guide: requests are signed exactly as Lazada's Signature algorithm page specifies, and Lazada's own result code — not the HTTP status — decides success. Test Connection calls Lazada's Get Seller and reports Connected only when Lazada returns the seller the token is bound to.
Builds published before 19.0.2.2.0 — and, on the other two series, before 17.0.2.2.1 /
18.0.2.2.1 — signed their requests in a way Lazada does not read, so Lazada answered every call
with MissingParameter and the old Test Connection reported success anyway. The currently
published builds are among them; the fix ships with the next release as a free update — and if anything still looks
wrong write to info@ecosire.com: integration support is included with
your purchase.
Half A — Lazada Open Platform
Lazada's developer console is Lazada Open Platform, https://open.lazada.com
(one console for all six markets — Singapore, Malaysia, Thailand, Indonesia,
Vietnam and the Philippines).
A1. Register and choose a role. Click Sign up on the Open Platform homepage and create the account, then register a role. A seller integrating its own shop chooses Software Developer ("if you need to integrate the Lazada Open API to query or update information in your store"); fill the registration page and click Completed (the logo must be exactly 200×200 px). Do not choose Service Provider — that role is for vendors selling software to other sellers and cannot be changed afterwards.
A2. Apply for the app category and create the app. Open App Management and click Create App. Under the Enterprise/Personal Self-Developed partner type locate Seller In-house APP, click Apply and give a reason. Lazada usually reviews the application the same working day. When the category shows Active, click it, then Create App at the bottom right, fill the form and click Confirm. Two fields to get right:
- Callback URL — enter your Odoo instance's address, for example
https://<your-odoo-host>/. It can be edited later; it must start withhttps://. The authorization link you build in A4 must use exactly this address or Lazada refuses with Redirect uri does not match the callback URL of the app. - App Logo — exactly 120×120 px.
A3. Read the app parameters. The app's details page shows:
| Lazada label | Odoo field | Notes |
|---|---|---|
| App Key | App Key | The identifier every request carries |
| App Secret | App Secret | Keep it on the server; never paste it into a support thread |
| App Status | — | Testing allows 10,000 calls a day and issues shorter-lived access tokens; click Apply Online (upper right) only when you are done testing — it is irreversible |
| Authorization Information / Authorized Seller Whitelist | — | See A4 |
| IP Whitelist | — | Optional; if you fill it, add your Odoo server's public IPv4 address (IPv6 is not supported) |
A4. Whitelist the seller and authorize the shop. A Seller In-house APP uses Lazada's Allow binding user to authorize policy: only sellers listed in the app's Authorized Seller Whitelist can authorize it. On the app's details page (or App Management → Auth Management) click Add under Authorized Seller Whitelist and enter the shop's Seller ID — the short code shown at the top left of Seller Center → Settings — the Seller Center login email and password, and the Country of the store. Then open the authorization link in a browser:
https://auth.lazada.com/oauth/authorize?response_type=code&force_auth=true&redirect_uri=https://<your-odoo-host>/&client_id=<App Key>
On Lazada's page select the store's site (Thailand, Malaysia, …, or Crossborder for a cross-border seller authorizing all sites), click Use Seller Login, sign in to Seller Center with the store's credentials (not a QR code — QR login is not accepted here), confirm the email shown under My Account is the store's, and click Authorize. Lazada redirects the browser to your callback address with the code in the query string:
https://<your-odoo-host>/?code=0_100132_Cl3VmMr6W6YC6cx6swxFAZ0l825
Copy the code. It must be exchanged within 30 minutes.
A5. Exchange the code for tokens. Call Lazada's GenerateAccessToken
endpoint, https://auth.lazada.com/rest/auth/token/create, with code,
app_key, timestamp (milliseconds), sign_method=sha256 and sign
(HMAC-SHA256 with the App Secret over the API path followed by the sorted
parameters, upper-case hex). The response carries the access_token
(expires_in, 7 days for an online app — shorter while the app is in
Testing), the refresh_token (refresh_expires_in, 30–50 days), the
store's country, and country_user_info with the seller_id and
short_code of each authorized store. If you would rather not run this
yourself, send us the code the moment you have it and we run the exchange
for you.
A6. Renewal. The access token is renewed with the refresh token at
/auth/token/refresh; when the refresh token itself expires the seller must
authorize again (repeat A4–A5). Lazada also stops sending push
notifications while the access token is invalid.
Half B — Odoo (17.0.2.2.1 / 18.0.2.2.1 / 19.0.2.2.1)
Sign in as a user who is a Lazada Manager (Settings → Users → the user → Lazada access field). Managers see the Configuration and Operations menus.
B1. Open the configuration list. From the Odoo apps menu open Lazada, then Configuration → Settings, and click New. One record is one store.
B2. Fill the Connection group.
| Field | Value |
|---|---|
| Configuration Name | Any name, e.g. the store's trading name |
| App Key | From the app's details page (A3) |
| App Secret | From the app's details page (A3) — the field is shown to Odoo administrators only |
| Access Token | From the token exchange (A5) — administrators only |
| Refresh Token | From the token exchange (A5) — administrators only |
| Region | The store's site: Singapore, Malaysia, Thailand, Indonesia, Vietnam or Philippines. This selects the API gateway (api.lazada.co.th for Thailand, and so on) |
| Timeout (seconds) | Leave at 30 |
| Company (in the Status group) | The Odoo company that owns this store's orders and stock |
Lazada URL can stay empty — the region chooses the gateway.
B3. Save, then click Test Connection in the form header. In the
corrected build this calls Lazada's Get Seller with the stored token and
sets Connection Status to Connected or Error with Lazada's reply in
Connection Error Message. In 19.0.2.2.1 the result is not a
verification of the credentials — see the note at the top of this section.
Operations → Test Connection offers the same check as a wizard.
B4. Choose what synchronizes — the Synchronization tab. Data Types (Sync Products, Sync Orders, Sync Customers, Sync Inventory) decide which areas the connector may touch; Auto Sync Customers and Sync Frequency decide whether the scheduled customer sync picks the store up. Product and order synchronization in this build is run by you, from Operations → Import Wizard and Export Wizard; there is no scheduled product or order import.
B5. First synchronization. Use Operations → Import Wizard (choose the data types and, for orders, the date range), then review Products, Orders and Customers. Settlements are loaded from Operations → Import Settlement.
B6. Where errors show. Connection Status / Connection Error Message on the configuration; Operations → Logs for one line per run with counts and the provider message; Operations → Queues for queued jobs and their retries; the Statistics tab for last-sync times and totals.
Field reference
Create a connection record on the lazada.configuration model. The fields the module defines for the connection are:
| Field | Technical name | Type | Required |
|---|---|---|---|
| Configuration Name | name | Char | Yes |
| App Key | app_key | Char | Yes |
| App Secret | app_secret | Char | Yes |
| Region | region | Selection | Yes |
| Company | company_id | Many2one | Yes |
| Lazada URL | lazada_url | Char | No |
| Access Token | access_token | Char | No |
| Refresh Token | refresh_token | Char | No |
| Marketplace | marketplace | Char | No |
| Settlement Clearing Account | settlement_clearing_account_id | Many2one | No |
| Webhook Shared Secret | webhook_secret | Char | No |
The fields marked Yes are enforced by the model — Odoo will not let you save the record without them. The technical name is the reliable identifier if your screen wording differs.
The same record carries these behaviour checkboxes:
| Checkbox | Technical name | What it governs |
|---|---|---|
| Sync Products | sync_products | Whether product and inventory work is allowed — the export wizard and the webhook dispatcher both check it |
| Sync Orders | sync_orders | Whether order topics from the webhook are processed |
| Sync Customers | sync_customers | Whether customer synchronization is allowed |
| Sync Inventory | sync_inventory | Whether the inventory push runs |
| Auto Sync Customers | auto_sync_customers | Whether the scheduled customer sync picks this configuration up |
| Auto Import Settlements | settlement_auto_import | Whether settlement files are imported automatically |
| Auto Invoice on Confirm | auto_invoice_on_confirm | Whether a confirmed Lazada order is invoiced automatically |
Leave anything you are not ready for switched off, and turn them on one at a time.
19.0.2.1.1auto_sync_products and auto_sync_orders no longer exist. They gated product and order sync
crons that had been withdrawn, so no code read them — a switch that promised automation the module
could not deliver. Product and order synchronization is operator-driven: run it from the
Operations wizards. The import wizard's own per-type checkboxes and sync-frequency field, and
the export wizard's include-images option, were removed for the same reason.
The module's own source contacts these hosts: api.lazada.sg, api.lazada.co.id, api.lazada.co.th, api.lazada.com.my, api.lazada.com.ph, api.lazada.vn, auth.lazada.com, open.lazada.com. Your firewall must allow outbound HTTPS to them.
Scheduled actions
The module installs 3 scheduled actions (Settings → Technical → Scheduled Actions):
| Scheduled action | Runs every | Enabled on install | What it does |
|---|---|---|---|
| lazada: Sync Customers | 6 hours | Yes | Syncs customers for every active configuration with Auto Sync Customers on |
| lazada: Test Connection | 1 day | Yes | Verifies each configuration's credentials still work |
| lazada: Cleanup Old Logs | 1 day | Yes | Trims the module's own sync-log records |
Intervals above are the shipped defaults. Adjust them to your volume — but be aware that the platform, not Odoo, sets the API rate limits, and shortening a sync interval is the usual cause of throttling errors in the logs.
Product, order and inventory synchronization is operator-driven in this release: run it from Lazada → Operations (Import Wizard, Export Wizard, Import Settlement) or from the actions on the configuration record. The webhook receiver below is the near-real-time path for order and product events.
Webhook and API endpoints your server exposes
These are the HTTP routes this module adds to your Odoo instance. Only the public one is reachable without an Odoo login.
| Endpoint | Auth | Purpose |
|---|---|---|
/lazada/webhook | public | Inbound Lazada push notifications. Verified: Lazada signs each delivery with Authorization: HMAC-SHA256(app_key + raw_body, app_secret) — the app's own credentials, not a per-store secret. The module checks it against every active Lazada configuration's App Key / App Secret to identify the seller account, then dispatches the payload's message_type/topic to lazada.sync.service. A delivery that verifies against no active configuration is answered HTTP 403 and never processed; malformed JSON is answered HTTP 400 |
/lazada/callback | logged-in user | Seller authorization callback. The Authorize with Lazada button opens Lazada's consent page; Lazada redirects the seller's browser back here with a one-time code and the state that binds it to one configuration record. The connector exchanges the code for the access and refresh tokens itself and lands the user back on the configuration form. A callback carrying an unknown or stale state is refused |
/lazada/api/status | logged-in user | connection and sync status read by the dashboard |
/lazada/api/sync | logged-in user | triggers a products / orders / customers sync for an active configuration. Present in the 17.0 and 18.0 builds; the 19.0 build runs the same syncs from the configuration form and the Operations wizards instead |
/lazada/dashboard/data | logged-in user | dashboard KPI data |
Register https://<your-odoo-host>/lazada/webhook as your push-notification URL in the Lazada Open Platform app console, and make sure the App Key and App Secret on the Lazada configuration record are the ones the app uses — that pair is what verifies every delivery. There is no separate webhook secret to configure: Lazada issues none for the Push Mechanism. A delivery whose signature does not verify against an active configuration is rejected with HTTP 403 and never processed.
403 on an unverifiable signature and 400 on a malformed body are the shipped behaviour. A signature mismatch is never answered with 200: the endpoint fails closed.
Order topics are skipped when Sync Orders is off, and product/inventory topics when Sync Products is off; the delivery is still acknowledged and the skip is recorded with its reason. Deliveries are recorded in lazada.webhook.log with their topic, payload and processing result, so a failing integration is diagnosable from Odoo.
Using the module
The module's menu is laid out as:
- Lazada → Dashboard
- Lazada → Orders
- Lazada → Products
- Lazada → Customers
- Lazada → Reverse Orders
- Lazada → Queues
- Lazada → Finance — Settlement Lines, Fee / GL Mapping
- Lazada → Operations — Import Wizard, Export Wizard, Mapping Wizard, Test Connection, Logs, Reports, Import Settlement, Backfill Combo BOMs
- Lazada → Configuration — Settings, Product Attributes
A normal first run is:
- Save the connection record and confirm the module reports a successful connection before importing anything.
- Review the mapping records so imported data lands on the right Odoo records.
- Run a small import first — restrict it by date or by a handful of products — and check the results before letting the scheduled actions take over.
- Watch the log records during the first full sync. Failures are recorded there rather than raised at the user.
Importing
The Import Wizard brings products, orders and customers into Odoo. From 19.0.2.1.1:
- Import Customers is a working action that honours the import limit and the create-missing, update-existing and map-only options, and records its progress, status and result on the wizard.
- Per-record product import works: an Import queue line fetches the item through Lazada's item-get call and creates or updates the mapped product template, detecting combo listings. Before this release every product queue line failed with a not-implemented error.
- Customer sync reads the buyer list by its real shape. Earlier builds read clone-era keys and stored every buyer with an empty Lazada id, so buyers could not be matched on a later run. Re-run the customer sync after upgrading to repair those records.
Exporting products, prices and stock
The Export Wizard is a real push from 19.0.2.1.1 — previously it reported an honest
not-implemented error. It creates and updates listings on Lazada and writes the returned item id
back onto the Odoo product template, so the two stay linked.
| Option | What it does |
|---|---|
| Export Limit | Caps how many products the run pushes |
| Update Existing | Updates products already mapped to a Lazada item |
| Create Missing | Creates unmapped products on Lazada |
| Include Variants | Pushes variant data alongside the template |
Inventory push sends quantity and price for every mapped template and stamps Last Inventory Sync on the configuration. It runs only when the configuration's Sync Inventory toggle is on.
Reverse orders, attributes and queues
Reverse Orders (Lazada's returns and cancellations) gained a full set of screens in 19.0.2.1.1: a search view with filters and group-bys, a kanban grouped by state, plus pivot and graph views for analysis.
Product Attributes are manageable from Configuration, with list and form views that surface the Is Sale Attribute marker distinguishing variant-forming attributes from descriptive ones. Queues has its own menu entry.
Dashboard
The OWL 2 dashboard shows KPI tiles with period-over-period deltas, a sales-trend line chart, an order-status doughnut, an activity feed, quick actions and a status footer.
From 19.0.2.1.1:
- Charts drill down. Clicking a day on the sales trend opens that day's Lazada orders; clicking an order-status segment opens the orders in that state.
- Amounts are formatted in the configuration's currency instead of a hardcoded dollar sign.
- Dashboard queries carry explicit limits, and opening the dashboard is the only action that creates its record — refreshing the data does not write anything.
- The dashboard's Sync button runs the customer sync, which is the real manual-sync surface. It previously called a route that had been withdrawn and did nothing.
Troubleshooting
Syncing
| Symptom | Cause and fix |
|---|---|
The requests library is required | requests is missing from Odoo's Python environment. Install it into the interpreter that runs Odoo. |
| The connection will not validate | Re-check every required field in the table above. Most failures are a mistyped secret, or credentials created for a sandbox while the module points at production (or vice-versa). |
| Webhook deliveries are all rejected | Webhook Secret is blank on every active configuration, or does not match the secret registered in the Lazada console. A failed check answers HTTP 403 and is recorded in lazada.webhook.log. |
| A webhook delivery is acknowledged but nothing happens | Sync Orders or Sync Products is off for that configuration; the skip and its reason are recorded on the log line. |
| Product or order sync never runs on its own | That is expected in this release — only customers are on a schedule. Run products and orders from Operations. |
| Every imported buyer has a blank Lazada id | An Odoo 19 build older than 19.0.2.1.1 read the wrong payload keys. Upgrade, then re-run the customer sync. |
| Export reports not implemented | An Odoo 19 build older than 19.0.2.1.1. Upgrade — export and inventory push are real from that release. |
| Sync starts then stops part-way | Read the module's log records for that run. Rate limiting and rejected field values are the two common causes; both are logged with the platform's own error text. |
| Records import but map to the wrong Odoo values | Fix the mapping records under the module's configuration, then re-run the import. |
| Duplicated products or customers | Run the initial import once. If a first attempt half-finished, check the existing records before re-running rather than importing on top. |
Version history
| Odoo version | Version you download today |
|---|---|
| 17.0 | 17.0.2.2.3 |
| 18.0 | 18.0.2.2.3 |
| 19.0 | 19.0.2.2.3 |
ECOSIRE module versions are <odoo major>.<module major>.<minor>.<patch>, so 19.0.2.2.3 is the Odoo 19 build of module version 2.2.3. Your installed version is shown in Apps.
17.0.2.2.3 / 18.0.2.2.3 / 19.0.2.2.3 — 28 September 2026
The dashboard shows what is really happening while it loads, fails or has no data. The same changes ship on all three series.
- Order Status draws its chart. The doughnut chart could stay blank under its legend even with orders on screen. Both dashboard charts are now drawn from the loaded figures once the page shows them.
- A chart with nothing to show says so ("No sales in this period", "No orders in this period") instead of an empty frame.
- The first load shows a loading skeleton and a message, not a row of zero figures that looked like a finished, empty dashboard. A first load that fails shows the error and a Retry button, with the quick actions still available, instead of an error above a page of zeros.
- The store name fits on a phone. A long store name stays on one line and is truncated (the full name shows on hover), and its icon now displays correctly.
- The Sales Trend axis states its scale. Amounts in thousands keep one decimal ("1.2K"), so 1,200 no longer reads "1K" next to the real 1,000 tick.
- Top Products bars compare revenue. The amount sits in a fixed, right-aligned column, so every bar has the same track length.
- Imported Customers fits a phone: shorter column labels, the sync status as a coloured badge, and the e-mail column available through the optional-columns toggle.
19.0.2.2.2 — 27 September 2026
- Every label on the dashboard is readable. Several status labels painted a colour on its own pale tint — the green badge was 2.04:1 against the 4.5:1 floor — and in dark mode the primary and sync buttons and the active period pill drew white on a pale blue accent (2.29:1, below the floor). Each tinted label now uses an ink colour chosen for that exact background, and the text on a filled button is its own token: the dark-mode accent reads 7.84:1 and the light accent stays at 6.38:1. Fill colours are unchanged — a status dot is still its own hue — so the dashboard looks the same and reads correctly, including in dark mode.
- The dashboard's four states are now covered by a test. Populated, empty, loading and error, plus the Customers list, each have a browser scenario with a real assertion, so a future release cannot regress the dashboard silently.
17.0.2.2.2 / 18.0.2.2.2 — 27 September 2026
- The same dashboard legibility fix, applied to both series and measured the same way. The
module's behaviour is otherwise identical to
17.0.2.2.1/18.0.2.2.1.
19.0.2.2.1 — 25 September 2026
- The connector really talks to Lazada. Requests are signed exactly as Lazada's Signature
algorithm page specifies, and Lazada's own result code — not the HTTP status — decides success.
Every call the connector makes is now read out of the module's pinned registry against Lazada's
published operation catalogue: the retired Fulfillment API paths (
/order/pack,/order/rts,/shipment/providers/get), the invented/reverse/order/*namespace and the delisted/finance/transaction/detail/getrow are gone, replaced by the operations Lazada actually serves. - "Push Inventory" pushes. The button on the configuration form sends price and sellable quantity for every product mapped to the store, reports how many Lazada accepted and how many it rejected, and names Lazada's own message for each rejection. One rejected SKU no longer stops the run.
- The dashboard answers for a named store. It reports which store the figures belong to and offers a store selector when you run more than one Lazada account. It reads only the company you are working in, so a multi-company database never shows one entity's Lazada numbers inside another's.
- The 17.0 and 18.0 builds were brought level with this one. Each series now ships the same connector, and each has its own entry below.
17.0.2.2.1 / 18.0.2.2.1 — 25 September 2026
- These two builds now speak Lazada's current API. Every earlier 17.0 and 18.0 build signed its
requests in a way Lazada does not read, so Lazada answered every call — product, order, stock,
finance and Test Connection alike — with
MissingParameterand nothing ever synchronized. Requests are now signed exactly as Lazada's Signature algorithm page specifies, and Lazada's own result code, not the HTTP status, decides success. - Only operations Lazada actually serves are called. The Fulfilment API paths Lazada retired on 30 April 2023, the invented reverse-order namespace and four delisted finance and warehouse lookups are gone, replaced by the operations the vendor's own catalogue lists.
- Push Inventory works, and the dashboard answers for a named store. Both fixes are the ones the 19.0 build received; on these two series they arrive in the same release.
- The module installs. The fee / GL account mapping form was missing a field Odoo 17 and 18 require on that view, which left the module uninstalled on a fresh database.
Check the version row at the top of this page for the build you downloaded.