Domain model¶
Every noun in the marketplace, what it means, and which table holds it.
The actors¶
| Actor | Identity | Authenticates with | Surface |
|---|---|---|---|
| Buyer | Shopware customer | Shopware storefront session | Storefront — buy-box, checkout |
| Seller | flyokai_seller bound 1:1 to a flyokai_user |
Portal JWT (OAuth password grant) | Seller portal /flyok-portal/* |
| Operator | flyokai_user with an operator/admin role |
Shopware admin token | Admin modules /api/_action/marketplace/* |
A seller is a marketplace account that lists offers, fulfils orders and gets paid. An operator is platform staff who approve sellers/offers, run finance and answer messages.
Seller¶
A seller is a flyokai_seller row joined to a flyokai_user (the login). Around
it hang:
- Branding (
flyokai_seller_branding) — store name, logo, banner; drives the seller microsite/seller/{slug}. - Addresses (
flyokai_seller_address) — billing / shipping. - Payout config (
flyokai_seller_payout_config) — bank holder, IBAN, SWIFT. - Stock sources (
flyokai_seller_stock_source) — the warehouses an offer's stock is held at. - Shipping profiles (
flyokai_shipping_profile+_service+_service_carrier) — how the seller's shipping maps onto cart service tiers. See Cart & checkout → Shipping. - A group (
flyokai_seller_group) — optional, carries a group-level commission default.
Sellers can be active, inactive or suspended. Operators manage them from
the Sellers admin; sellers self-serve profile, branding and
addresses from the portal.
Product ownership¶
A product is either operator-owned (the platform's own catalogue) or
seller-owned (created by a seller through the portal or bulk import). The
owner is recorded in product.flyokai_product_owner_id — NULL for
operator-owned.
Ownership gates what a seller may touch: a seller can only edit, offer on via bulk import, or manage stock for their own products. Operator-owned products are open for any seller to make an offer against. The bulk import ownership guard enforces this on every CSV row.
Newly seller-created products are subject to the autoApproveProducts setting:
off (default) → they land pending approval until an operator reviews them;
on → sellers can publish directly.
Offer¶
An offer (flyokai_seller_offer) is one seller's proposition to sell one
product at a price, with stock and shipping. Multiple sellers' offers on the same
product compete for the buy-box.
flyokai_seller_offer one row per (seller, product/variant)
├─ flyokai_seller_offer_price price tier(s) — qty range → price
└─ flyokai_seller_offer_stock stock per stock-source (warehouse)
Offers are per-variant
On a configurable (variant) product, offers attach to the child
variants, not the parent. The parent carries no offer of its own — the
buy-box is resolved per variant. Tools exist to backfill variant offers when
migrating (flyokai:marketplace:backfill-variant-offers).
Offer lifecycle¶
create / material edit
(draft) ───────────────────────► pending_approval ──► active
│ ▲ │
operator reject│ │operator │seller pause /
▼ │approve ▼operator action
rejected inactive
- New and materially edited offers land in
pending_approvalunlessautoApproveOffersis on (then the seller may publish straight toactive). - Operators approve or reject from the Offers admin.
- Only
activeoffers participate in the buy-box.
Purchase order (PO)¶
When a buyer checks out, the single Shopware order fans out into one
purchase order per seller (flyokai_purchase_order), each with its own
lines (flyokai_purchase_order_line), status, totals, commission and (later)
payout link.
A PO advances through pending → confirmed → shipped → delivered (or
cancelled), driven by Shopware delivery state transitions. Each PO line
snapshots the seller_offer, quantity, unit price and commission percent at
the moment of sale — so the figures never drift when products or offers change
later. Sellers see their POs read-only in the portal; operators see all of them
in Finance.
Commission & fees¶
What the platform keeps from a sale:
| Knob | Where | Resolution order |
|---|---|---|
| Per-product commission | product.flyokaiCommissionPercent |
Used first when set (and non-zero). |
| Global default commission | defaultCommissionPercent config |
Fallback when the product has none. |
| Fixed per-PO transaction fee | defaultTransactionFeeAmount config |
Flat amount deducted from each PO's payout. |
Both are snapshotted onto the PO line at order placement — the value in force at checkout applies to that PO for life. See Configuration → Marketplace.
Statement¶
A statement (flyokai_statement, lines in flyokai_statement_line) rolls a
seller's POs over a closed date interval into a payable figure: total sales,
total commission, and the resulting payout_amount. Optionally shipping the
seller collected is added back in (includeShippingInPayout).
Statements are open → closed → paid. Open statements can be recomputed to pick
up config changes; closed/paid statements are frozen. Generated via
marketplace:statement:generate or the Finance admin.
Full mechanics in Statements & payouts.
Payout¶
A payout (flyokai_payout) is a money movement to a seller against a closed
statement, carrying the bank details snapshotted from the seller's payout config.
Status runs pending → executing → completed. Created and executed via
marketplace:payout:execute or the admin. Execution is the integration
point where you wire your PSP / bank file — out of the box it records the
movement.
Messaging¶
Seller ↔ operator mail is threaded:
flyokai_chainis a thread;flyokai_mailare the messages in it.flyokai_mail_recipienttracks unread counts;flyokai_mail_pending_sendis the outbox batch.
Delivery goes through Shopware's own mailer (MailerInterface). See
Messaging.
The tables¶
The Base plugin owns 23 data-plane / identity DTOs, all prefixed
flyokai_, reconciled into Shopware's MySQL on install:
| Group | Tables |
|---|---|
| Identity | flyokai_user |
| Sellers | flyokai_seller, flyokai_seller_group, flyokai_seller_address, flyokai_seller_branding, flyokai_seller_payout_config, flyokai_seller_stock_source |
| Offers | flyokai_seller_offer, flyokai_seller_offer_price, flyokai_seller_offer_stock |
| Orders | flyokai_purchase_order, flyokai_purchase_order_line |
| Finance | flyokai_statement, flyokai_statement_line, flyokai_payout |
| Shipping | flyokai_shipping_profile, flyokai_shipping_profile_service, flyokai_shipping_profile_service_carrier, flyokai_shipping_service |
| Messaging | flyokai_chain, flyokai_mail, flyokai_mail_recipient, flyokai_mail_pending_send |
Plus DAL extensions on Shopware's product, order_line_item and
order_delivery (see Architecture → DAL extensions).
The OAuth client/token tables (identity plane) are created alongside on install but are managed by the OAuth layer rather than the marketplace schema DTOs.
Every term again, alphabetical, in the Glossary.