Skip to content

Repository files navigation

donhang

A read-only packing worklist for one Etsy shop. Orders that still need to go out sit at the top, and everything outstanding is totalled into one pick list so you know what to pull off the shelf before you start.

Đơn hàng is Vietnamese for "orders".

donhang is a personal, non-commercial tool used by one person on one computer. It holds read-only access and writes nothing to Etsy. The term "Etsy" is a trademark of Etsy, Inc. This application uses the Etsy API but is not endorsed or certified by Etsy, Inc.

The queue

What it does

  • Lists the connected shop's 50 most recent orders, unshipped first — the point of a queue.
  • Each order shows its items and quantities, the total, the delivery address, and the buyer's message, all on screen at once so you can pack straight from it.
  • Totals every unshipped line into one pick list — the thing you actually want before packing, and the thing an order page can never show you.
  • Shows the tracking already recorded on orders that have gone out.
  • Falls back to sample data when nothing is connected, so the whole interface works before any key exists.

What it will not do

It has no write path — no marking shipped, no editing, no messaging. It asks Etsy for read scopes only, and every call it makes to /v3/application/… is a GET. (The one POST in the source is the OAuth token exchange at /v3/public/oauth/token, which the protocol requires and which carries no shop data.) Shipping is done on Etsy; this page reflects it on the next refresh.

Queue Shipped
To ship Shipped

Run it

node main.js        # http://localhost:3007
npm run dev         # same, with --watch

There is nothing to install. No dependencies, no bundler, no build step — Node's standard library only, and not a single line of JavaScript is served to the browser.

With no .env present it starts in demo mode.

Connect a real shop

  1. Register an application at https://www.etsy.com/developers/register. Describe it truthfully: a private order queue used only by the shop owner.
  2. On the Etsy app settings, add this Callback URL exactly: http://localhost:3007/auth/callback
  3. cp .env.example .env and paste the keystring into ETSY_KEYSTRING.
  4. Restart, open the page, press Connect my Etsy shop, approve the scopes.

Scopes

Scope Why
shops_r resolve which shop authorised the app
transactions_r read that shop's receipts — the orders themselves

Two read scopes, no write scope. An Etsy account with no shop can connect, it will simply have no receipts to show.

Files

main.js            http server, routes, .env reader — node:http, no framework
etsy.js            Etsy v3 client: OAuth PKCE, token refresh, two GETs
orders.js          the single normalizer both live and demo data pass through, plus the pick list
mock.js            demo receipts in RAW Etsy shape (see below)
views.js           server-rendered HTML, no client JS
store.js           data/tokens.json — tokens + cached shop id, git-ignored
public/            style.css, favicon.svg, and the four static pages

One shape, enforced by one function

Demo data is emitted in the raw Etsy receipt shape and normalized by the same normalizeReceipt() that live responses go through. A field that breaks in production breaks in the demo too. (The alternative — a mock that emits already-normalized objects — lets the two drift apart silently, which is a real bug I did not want to repeat.)

Notes on the Etsy API

  • x-api-key is normally the bare keystring on OAuth calls, but some requests want keystring:shared_secret and say so in neither the docs nor the error body. Set ETSY_SHARED_SECRET in .env and the client sends the pair.
  • The v3 access token carries the user id in front of the first . — there is no "me" endpoint.
  • Money arrives as an integer plus a divisor; orders.js divides once and keeps the currency code alongside.
  • Access tokens last an hour and are refreshed a minute early.

Data handling

Orders are fetched per page view and held in memory only long enough to render. Nothing about an order — buyer name, address, message — is written to disk, logged, or sent anywhere but back to Etsy. The only file the app writes is data/tokens.json.

Pages

Page URL
Queue / · /?show=shipped · /?show=all
What this is /about
Privacy /privacy
Terms of use /terms
Contact /support

Licence

MIT.

About

A read-only Etsy order and packing worklist. Unshipped orders first, every outstanding line totalled into one pick list. Node standard library only, runs locally.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages