- JavaScript 92.1%
- Python 4.2%
- HTML 2%
- CSS 1.7%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
Two things a table rule and a control's edge do not have in common. Fields and plain buttons draw no fill of their own: an input takes the page background and a button is transparent, so the 1px border is the only thing saying "this is a control". It was --border, the same hairline used between table rows, at 1.44:1 against the page where WCAG 1.4.11 asks 3:1 of any boundary that identifies a component. Rather than darken one token and make every table heavier, controls now take --field-border and the rules stay as faint as they were. The dark value is stepped against --surface rather than --bg, since a field inside a settings card is surrounded by the lighter of the two: the value that cleared 3:1 on the page alone came to 2.92:1 there. The Trends page rendered the seller breakdown twice, a donut and a stacked bar under headings that said the same thing, off the same figures. The bar came first and the donut superseded it in 1.1.0 without removing it. Its palette was also eight literals sitting outside both theme blocks, so it never changed for dark mode, and it indexed by position modulo eight, which repeated a colour as soon as a ninth seller appeared. Removing the renderer leaves shareBar itself in place, since donutChart is built on it. The mockup follows: it reads the same tokens, so a control drawn there has the edge the product gives it. |
||
| .forgejo/workflows | ||
| analytics | ||
| api | ||
| background | ||
| content | ||
| database | ||
| doc | ||
| exporters | ||
| img | ||
| parsers | ||
| tests | ||
| tools | ||
| ui | ||
| utils | ||
| .gitignore | ||
| CHANGELOG.md | ||
| LICENSE | ||
| manifest.json | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
| spec.md | ||
| VERSION.md | ||
| WISHLIST.md | ||
firefox-lazada-order-exporter
Export your own Lazada order history to CSV, JSON and a local archive
Supports Lazada Philippines (lazada.com.ph) only.
Other Lazada markets are not supported - see the wishlist for why.
Support: support@jdneer.com
Every figure above is fabricated. Sellers, amounts and dates are invented for the illustration.
Lazada has no buyer export. This Firefox extension reuses the session you are already logged into, reads the same APIs the Lazada order page uses, and saves everything locally. Nothing is uploaded anywhere.
Install
Three ways, depending on what you want.
1. From addons.mozilla.org (recommended)
Lazada Buyer Order Exporter (Philippines) on addons.mozilla.org
One click, works in release Firefox, survives restarts, and updates itself. This is the route for using the extension rather than working on it, and it is the only one where the archive is not at risk from a restart.
2. Load it temporarily, for development
Works in any Firefox, including release, and needs no signing. The add-on is discarded when Firefox closes.
Download lazada_buyer_order_exporter-<version>.xpi from the
latest release,
or build it yourself:
git clone ssh://git@git.jdneer.com:29500/jd/firefox-lazada-order-exporter.git
cd firefox-lazada-order-exporter
npm ci && npm run build # -> dist/lazada_buyer_order_exporter-<version>.xpi
Then:
- Type
about:debuggingin the address bar and press Enter. - Click This Firefox in the left sidebar.
- Click Load Temporary Add-on...
- Select the
.xpi. (In the file picker you may need to switch the filter to All Files.) - It appears under Temporary Extensions, and its icon appears in the toolbar. If you do not see the icon, click the puzzle-piece Extensions button and pin it.
⚠️ A temporary add-on loses its archive when you remove it or restart Firefox. The Reload button in
about:debuggingkeeps it; Remove and re-add does not. See Back up before updating.
3. Permanently, from your own build
For running a build of your own - a fork, or a change you have made - without going through addons.mozilla.org. Release Firefox will not install an unsigned add-on permanently, so this needs either:
- Firefox Developer Edition, Nightly or ESR. Set
xpinstall.signatures.requiredtofalseinabout:config, then install fromabout:addons> gear icon > Install Add-on From File... - A signed build. Sign it against your own addons.mozilla.org account. See VERSION.md.
Use
- Log in at https://www.lazada.com.ph/ as normal.
- Click the extension icon. It should say Logged in. Any Lazada page will do.
- Click Start Full Sync. It opens the My Orders page itself and works through your history.
- When it finishes, open the dashboard and click Export CSV.
A first sync is an overnight job, and deliberately so - see Pacing below. It checkpoints after every page, so it can be paused, interrupted and resumed.
A sync runs in four phases - order list, order details, tracking, returns - and
the dashboard shows which one is going. Only the first has finished when the
page counter stops moving, so dates and carriers read as 0 on the Overview
until the later phases run. That is work pending, not data missing.
If the popup says No My Orders tab, that is not a login problem; starting a sync opens the page it needs. If it says Not logged in while you are signed in, that is a bug worth reporting.
Pacing
Requests are deliberately conservative: a random 8-20 second gap, and a two-minute pause every 25 requests. The point is to put as little load on Lazada as a person browsing would, and to stay well inside the limits their service protections enforce.
Running it faster does not work. Sustained requests at a shorter interval reach the thresholds Lazada's automated protections act on - first a slider captcha, then a network-level block that applies to your whole connection and cannot be dismissed. Read doc/RATE-LIMITING.md before changing these settings.
If Lazada does present a challenge, the sync stops and waits for you. It does not retry the challenge, work around it, or attempt to solve it. Clear the captcha in your browser and press Resume; if it was the network-level block, leave it a few hours first.
Stopping a sync
Pause stops at the next safe point and keeps the checkpoint, so Resume carries on where it left off. Cancel stops the run for good: everything already archived is kept, but that run cannot be resumed and a later sync starts from the beginning. Use Pause unless you mean it.
What you get
Exports. accounting.csv, one row per order line, with dates, totals,
payment method, seller, product photo, tracking number, carrier, delivery dates,
returns and refunds. Plus relational CSVs per table, a JSON export, an XLSX
workbook, a delivery-performance report and a combined-order reconciliation
report.
Custom layouts. Pick the columns, their order and their headings, or start from a preset for QuickBooks, Xero or a Philippine BIR expenses ledger.
Browse. Orders, shipments, order lines, returns and extraction errors as sortable, filterable tables.
Trends. Spend by month, quarter or year; by seller, payment method or a keyword you supply. Repurchase intervals and unit-price history per product, return rate by seller, and delivery times by carrier over time - all computed locally, Lazada never contacted.
The full list is in doc/FEATURES.md.
Requirements
- Firefox 140 or newer
- A Lazada Philippines account
- Node.js 20+ to build, not needed to use a downloaded
.xpi
Settings
Pacing, retention, logging and export options, all in the dashboard with hover help on each one. doc/SETTINGS.md lists them.
The pacing defaults are slow on purpose - see Pacing above and doc/RATE-LIMITING.md.
Back up before updating
This applies to the temporary install in route 2 above, not to an install from addons.mozilla.org.
A temporary add-on gets a new storage area every time it is added, so
loading a new build - or restarting Firefox - starts from an empty archive. The
Reload button in about:debugging keeps it; nothing else does.
So before switching versions: Backup > Back up archive, then Restore after. A backup carries every store including sync progress, so a paused sync can carry on. Restoring merges and never deletes.
Privacy
Your archive holds your name, phone number, addresses and full purchase history, plus sellers, products, tracking, returns and refunds.
- Nothing is collected or transmitted. There is no server, no telemetry, no analytics and no remote code. The only network requests are to Lazada, and they carry nothing beyond what a request from the Lazada page itself would.
- Nothing reaches the developer. Your data goes to your browser's storage and to files you ask for, and nowhere else.
- Exports stay on your machine, saved through the browser's own download handling.
- Read-only. It never places, changes or cancels an order, and never alters an account setting.
- No password, and no cookie handling. The extension never asks for your password, and it does not read, store or transmit your Lazada cookies. Requests are issued from inside a Lazada page in your own browser, so the browser attaches your existing session itself - the extension never sees it.
- No affiliation. This is an independent tool. It is not made by, endorsed by, or connected to Lazada.
Permissions, and why each one exists
| Permission | Why |
|---|---|
storage, unlimitedStorage |
The local archive. An order history runs to tens of megabytes |
downloads |
Saving the exports and backups you ask for |
tabs |
Finding or opening the Lazada tab that requests are issued from |
notifications |
Telling you a sync paused, since it runs for hours with no window open |
my.lazada.com.ph, member.lazada.com.ph |
The only two hosts contacted. Order data and sign-in state respectively |
No other host is requested, and no browsing outside those two domains is observed.
Documentation
| Document | What |
|---|---|
| doc/FEATURES.md | Everything the extension does |
| doc/SETTINGS.md | Every setting, what it does, and what not to touch |
| doc/RATE-LIMITING.md | Why the defaults are slow, and how accounts get flagged |
| doc/LAZADA-API.md | The reverse-engineered Lazada API contract |
| doc/VERIFICATION.md | Which field mappings are proven, and what is still inferred |
| doc/DEVELOPMENT.md | Layout, tests, fixtures, CI, adding a market |
| VERSION.md | Versioning, tagging, signing |
| doc/UPDATES.md | How updates work, and why update_url is not set |
| CHANGELOG.md | What changed per release |
| WISHLIST.md | Deferred work |
| spec.md | The original build specification |
Support
support@jdneer.com for questions, bug reports and feature requests.
What helps in a report:
- The version, shown at the bottom of the dashboard sidebar.
- The Diagnostics page. Its output is redacted before it is shown - no order numbers, no names, no addresses - so it is safe to paste into an email.
- What you were doing, and which of the four sync phases was running.
What not to send: your archive backup or your exports. They contain your full order history, your name, your phone number and your delivery addresses. Nothing in a bug report needs them, and no reply will ever ask for them.