[portfolio](https://geonwoo.kim/en/portfolio) › deepeet

# Order automation

https://geonwoo.kim/en/portfolio/deepeet-order-engine

Period: 2026.07 — 2026.08

deepeet started as a consignment business selling fruit from wholesale suppliers on Coupang and Toss Shopping. Each order needs a supplier, a purchase order and payment, and the supplier's tracking number registered back on the sales channel. This was the first job deepeet automated. The first paid customer order went to a supplier automatically, and the flow was then extended through confirmed delivery.

This was the first thing deepeet built. It carries each order from customer payment to purchase order, tracking number and confirmed delivery.

Team: Solo

Role: Workflow definition and domain design · Sales channel and supplier integrations · Unattended purchasing and recovery · Purchase tracking

Go · chi · PostgreSQL · pgx · sqlc · goose · OpenAPI · MinIO · Xvfb

- Order collection that stores sales-channel orders in one shared model without duplicates
- Dry-run purchasing that links order items to supplier products and shows candidates and costs without placing orders
- Purchase files that follow each supplier's spreadsheet template
- Unattended purchasing, payment and tracking collection with a job queue and duplicate-order protection
- Tracking through the sales channel's official delivery confirmation
- Pause and resume of automatic purchasing and payment per order or option

## Purchase orders and payments with lost responses

Problem: When a response is lost after sending a purchase order or payment to a supplier, there is no way to tell whether it went through.

Solution: Requests with unknown results are marked as such and are not resent until an official supplier lookup confirms the outcome. They are not resubmitted to another supplier either. Suppliers where submission includes payment and those with a separate payment API are recorded separately. Retries cannot place or pay for the same order twice.

## Handoffs lost to outages and network drops

Problem: If the server stopped after reading a tracking number from a supplier but before registering it on the channel, the next step was never created.

Solution: External lookup results are recorded together with the next processing step. If the server stops, processing restarts from the last point saved in the database. Remaining purchase and tracking handoffs continue even after a long outage.

## Orders that lose money

Problem: If supply costs rise after a sale price is set, every new order can deepen the loss.

Solution: Just before submission and payment, the system recalculates from the actual payment minus fees, VAT and supply cost. Purchasing is blocked when the contribution margin is negative or cannot be verified.

## Bot blocking on supplier logins

Problem: When a supplier site blocked automated access at login, purchasing and tracking collection stopped.

Solution: A browser runs on a virtual display on the server to recover the login, and the session is handed safely to the backend. Operators are never asked to work in a local browser.

## A pause button colliding with running purchases

Problem: Saving an option pause competed for a lock with supplier re-evaluation and failed with HTTP 500.

Solution: The lock switched to shared mode so independent work runs in parallel, while real purchases and pauses still queue on it. Long waits return a 409 conflict before saving. A single order can resume even while the whole option is paused.

## Architecture

### Sales channels

- Order collection

  Coupang · Toss Shopping · resumes from the last successful point

- Tracking registration

  Supplier tracking numbers registered on channels · confirmed by official lookup

### Purchase execution

- Job queue

  One runner per job for a set time · retries · duplicate-order protection

- Supplier integrations

  Submission · payment · tracking collection · per-supplier payment modes

- Server browser

  Recovers supplier login sessions

### Records

- Step-by-step processing records

  External lookup results recorded with the next processing step

- Audit history

  Existing history kept, only new events appended · held when the outcome is unknown

Order received → Candidate selected → Product prepared → Supplier submission → Supplier payment → Shipment and tracking check → Channel tracking registration → In-transit check → Delivery confirmation


[Product listing](https://geonwoo.kim/en/portfolio/deepeet-listing-pipeline) · [vortesso · coffee journal app](https://geonwoo.kim/en/portfolio/vortesso)
