seller-backend (v2.0.0)
Integration gateway between external marketplaces (Shopee, iFood) and the Daki own channel. Handles order reception, catalog synchronization, campaign management, quotation, and publishes the canonical seller order lifecycle (contract v2, with GMV / net GMV).
Service Overview
The seller-backend service is the integration gateway between sales channels and the Daki ecosystem. It receives orders from external marketplaces (Shopee, iFood) and from the Daki own channel, normalizes them to the internal format, injects them into the fulfillment pipeline via ordr (new_order on Pub/Sub), and publishes the canonical seller order lifecycle (seller_order.*, contract v2) consumed by the financial services (mony, paym).
It runs as a single binary dispatched by argument: shopee (default) | daki | ifood | consumers | worker.
Key Features
- Order Management: Receives orders from marketplaces (webhook/API) and creates them in the ORDR system
- Canonical Order Lifecycle: Publishes
seller_order.*v2 events with GMV and net GMV (all monetary values in cents) - Catalog Synchronization: Syncs product prices, inventory, and content between Daki and marketplaces
- Campaign Management: Creates and manages promotional campaigns on marketplaces
- Quotation: Provides freight quotations for marketplace orders
- CRM Fan-out (daki channel): Faktory jobs to Ticketer, Braze, Topsort, User Profile and User Order History
Architecture
- Language: Go · Framework: Gin · Database: PostgreSQL · Cache: Redis
- Messaging: Kafka (seller order lifecycle, deliveries, invoices, inventory, bills) and GCP Pub/Sub (
new_orderto ordr, catalog price updates) - Async jobs: Faktory (daki channel CRM fan-out)
API Endpoints
Common (all app modes, port 8080)
| Method | Path | Purpose |
|---|---|---|
| GET | / | Healthcheck |
| PUT | /api/v1/catalog/product-content | Update product content from the hub (triggers marketplace sync) |
| POST | /api/v1/catalog/reset | Full catalog reset |
| POST | /api/v1/seller_orders/:id/stock_reserved | Fulfillment callback: stock reserved ({movement_id?}) |
| POST | /api/v1/seller_orders/:id/ready | Order picked/ready ({picked_items: [{sku, quantity_picked}]}) |
| POST | /api/v1/seller_orders/:id/cancel | Cancel order ({reason?}) |
:id is the order DakiID.
Shopee mode
| Method | Path | Purpose |
|---|---|---|
| GET | /api/v1/auth/url | Generate Shopee OAuth URL |
| GET | /api/v1/auth/generate-token | Exchange OAuth code for token |
| POST | /api/v1/daki-quotes/quote | Freight/delivery quotation for Shopee |
| POST | /api/v1/shopee/webhook/orders/update_status | Shopee order status webhook |
| DELETE | /api/v1/catalog | Remove products from the Shopee store |
| POST | /api/v1/catalog/update_price_inventory | Update price/inventory on Shopee |
Daki mode
| Method | Path | Purpose |
|---|---|---|
| POST | /api/v1/seller_orders | Create a Daki channel order (placement). Idempotent by idempotency_key; returns 201 {seller_order_id} |
iFood mode
| Method | Path | Purpose |
|---|---|---|
| POST | /api/v1/seller_orders | Ingest an iFood order |
| POST | /api/v1/seller_orders/:id/cancelled | Cancellation coming from the iFood marketplace |
Events Produced
seller_order.*(Kafka topicseller_orders.out, key = DakiID,meta.version = 2): canonical order lifecycle for all channels —created,confirmed,canceled,delivered,ready,on_the_way. Payload includesgmv,net_gmv,total_discounts(= gmv − net_gmv), and the payment splitpayment_fraction/refund_wallet_fraction(cents, not 0–1 fractions). Consumed by mony and paym.new_order(GCP Pub/Sub topicORDR_TOPIC→ordr-input, ordering key = DakiID): injects the normalized order into the ordr fulfillment pipeline.
Events Consumed
delivery.*(Kafkadeliveries.out): updates order status per delivery status (ready,on_the_way,delivered,canceled,arrived,picking) and relays progress signals (rider.assigned,checked_in,done) to CRM on the daki channel.invoice.created(Kafkainvoices.out): NF-e issued → triggers the marketplace invoice flow (e.g. Shopee GCS upload).warehouse_product_inventory.updated(Kafkawarehouse_product_inventories.out): syncs stock to the marketplace.bill.*(Kafkabills.out, daki channel only): snapshots the bill; onbill.paidfills the payer document when absent and triggers CRM.- Catalog price updates (GCP Pub/Sub, topic via
PRICE_UPDATE_TOPIC, subscriptionseller-backend-price-update-subscription): stamps prices/campaigns on Shopee. Internal event, not documented in the catalog.