Skip to content

Marketplace Order Management ​

Flow ID: AD-11 Module(s): eshop, webhooks Complexity: High Last Updated: 2026-04-04

Business Context ​

Three marketplace integrations receive external orders and convert them into internal shop orders: Skroutz SmartCart (webhook-based, real-time), Shopflix (polling-based), and Public Marketplace/Mirakl (polling-based). Each has its own order lifecycle, stock validation, and fulfillment flow. All create "fake carts" and guest customers to generate internal orders.

Entry Points ​

TypePath / TriggerControllerMethod
WebhookSkroutz new_order / order_updatedecommercen/webhooks/AdvSmartCart.phphandle()
CronShopflix pollingAdvHandleShopflixOrders jobexecuteCommand()
CronPublic marketplace pollingAdvGetPublicMarketplaceAwaitingOrders jobexecuteCommand()
AdminSkroutz ordersecommercen/eshop/controllers/Adv_skroutz_orders_admin.phpindex(), accept(), reject()
AdminShopflix ordersAdv_shopflix_orders_admin.phpindex(), accept(), reject()
AdminPublic ordersAdv_public_orders_admin.phpindex(), accept(), reject()

Architecture Comparison ​

AspectSkroutzShopflixPublic (Mirakl)
SyncWebhook push (real-time)Polling pull (job)Polling pull (job)
Product lookupshop_product.skroutz_id + size/color attributesproduct_codes.product_code exact matchEAN/product code
RejectionLine-item level with reason codesFull order onlyLine-item level
Express ordersAuto-accept if express=trueN/AN/A
InvoiceSeparate skroutz_invoice_details tableFields in main orderadditional_fields JSON
VouchersVia standard transporter flowJSON array in shopflix_vouchers columnMirakl handles
Auto-cancelVia webhook state changeIf status becomes I (Cancelled) or D (Rejected)Manual only
Provider tagskroutz_smart_cartshopflix_marketplacePUBLIC_MARKETPLACE_PROVIDER

Common Flow Pattern ​

All three follow the same pattern for order acceptance:

  1. Receive order (webhook or poll) → store in marketplace-specific table
  2. Admin reviews in marketplace order listing
  3. Stock validation — getLiveProductsParsed() checks productAvailabilityStocks >= quantity. Bypassable via DISABLE_PRODUCT_STOCK_CHECK registry.
  4. Accept via API — calls marketplace API to confirm acceptance
  5. Create internal order — builds fake cart, creates guest customer, calls order_model->create_order_admin() with status=PAID
  6. Fire ERP hook — internalApiOrderForErpHook()

Business Rules ​

RuleDescription
All accepted orders = status PAIDMarketplace orders are pre-paid externally
Stock check bypassableDISABLE_PRODUCT_STOCK_CHECK registry flag
Skroutz auto-cleanupOrders 5+ days old without shop_order_id are auto-deleted
Shopflix auto-cancelIf polling detects status I or D, internal order is auto-canceled
Guest customers created per orderEach marketplace order creates a new guest customer
Skroutz express auto-acceptExpress orders skip manual acceptance

Data Model ​

TableMarketplacePurpose
skroutz_ordersSkroutzOrder header (code, state, courier, expires_at)
skroutz_line_itemsSkroutzOrder items (shop_uid, quantity, price)
skroutz_invoice_detailsSkroutzInvoice data (company, VAT, DOY)
shopflix_ordersShopflixOrder header (order_id, status, shipment_ids)
shopflix_line_itemsShopflixOrder items (product data, quantity, price)
public_ordersPublicOrder header (order_id, state, total_price)
public_line_itemsPublicOrder items (order_line_id, ean, quantity)

Marketplace Activity Status (Live Production Data) ​

Based on live production data across deployed clients:

MarketplaceTableApproximate RowsStatusNotes
Skroutz SmartCartskroutz_orders~46,000+ActivePrimary marketplace. Webhook-driven, real-time. Multiple clients active.
Shopflixshopflix_orders0InactiveCode exists, no production usage. Shopflix marketplace was discontinued.
Public/Miraklpublic_orders0InactiveCode exists, no production usage. Requires Mirakl API credentials.
IRISiris_orders0InactivePayment-linked orders (IRIS payment gateway), not a traditional marketplace.
JCCjcc_order_ids0InactivePayment-linked orders (JCC payment gateway, Cyprus), not a traditional marketplace.

Key finding: Skroutz SmartCart is the only actively used marketplace integration. All other marketplace integrations exist in code but have zero production usage. IRIS and JCC are not true marketplaces -- they are payment gateway order ID linking tables.

REST API Endpoints (Marketplace Module) ​

The modern REST layer exposes read-only endpoints for all marketplace entities at src/Rest/Marketplace/. All endpoints require JWT authentication.

Skroutz Endpoints ​

MethodPathControllerStatus
GET/rest/marketplace/skroutz/orderSkroutzOrder::index()200 (active data)
GET/rest/marketplace/skroutz/order/itemSkroutzOrder::item()200
GET/rest/marketplace/skroutz/order/{code}SkroutzOrder::show()200
GET/rest/marketplace/skroutz/line-itemSkroutzLineItem::index()200
GET/rest/marketplace/skroutz/line-item/itemSkroutzLineItem::item()200
GET/rest/marketplace/skroutz/line-item/{id}SkroutzLineItem::show()200
GET/rest/marketplace/skroutz/invoice-detailSkroutzInvoiceDetail::index()200
GET/rest/marketplace/skroutz/invoice-detail/itemSkroutzInvoiceDetail::item()200
GET/rest/marketplace/skroutz/invoice-detail/{id}SkroutzInvoiceDetail::show()200

Shopflix Endpoints ​

MethodPathControllerStatus
GET/rest/marketplace/shopflix/orderShopflixOrder::index()200 (empty result set)
GET/rest/marketplace/shopflix/order/itemShopflixOrder::item()200
GET/rest/marketplace/shopflix/order/{id}ShopflixOrder::show()200
GET/rest/marketplace/shopflix/line-itemShopflixLineItem::index()200 (empty result set)
GET/rest/marketplace/shopflix/line-item/itemShopflixLineItem::item()200
GET/rest/marketplace/shopflix/line-item/{id}ShopflixLineItem::show()200

Public/Mirakl Endpoints ​

MethodPathControllerStatus
GET/rest/marketplace/public/orderPublicOrder::index()200 (empty result set)
GET/rest/marketplace/public/order/itemPublicOrder::item()200
GET/rest/marketplace/public/order/{id}PublicOrder::show()200
GET/rest/marketplace/public/line-itemPublicLineItem::index()200 (empty result set)
GET/rest/marketplace/public/line-item/itemPublicLineItem::item()200
GET/rest/marketplace/public/line-item/{id}PublicLineItem::show()200

IRIS Endpoints ​

MethodPathControllerStatus
GET/rest/marketplace/iris/orderIrisOrder::index()200 (empty result set)
GET/rest/marketplace/iris/order/itemIrisOrder::item()200
GET/rest/marketplace/iris/order/{id}IrisOrder::show()200

JCC Endpoints ​

MethodPathControllerStatus
GET/rest/marketplace/jcc/orderJccOrder::index()200 (empty result set)
GET/rest/marketplace/jcc/order/itemJccOrder::item()200
GET/rest/marketplace/jcc/order/{id}JccOrder::show()200

Note: All write endpoints (POST, PUT, DELETE) are commented out in rest_routes.php for all marketplace entities. Only GET (read) operations are exposed.

IRIS and JCC Detail ​

IRIS and JCC are not traditional marketplace integrations. They are payment gateway order ID linking tables:

  • iris_orders: Links IRIS payment gateway order IDs (irisOrderId, messageId, initiatingPartyRefId) to shop_order_id. Can also link to gift_card_orders_id for gift card payments.
  • jcc_order_ids: Links JCC (Cyprus) payment gateway order IDs (jcc_order_id) to shop_order_id.

These exist in the REST Marketplace module for API consistency but are functionally payment record linkage, not marketplace order management.

Data Model (Detailed Column Reference) ​

skroutz_orders Table ​

ColumnTypeDescription
codeVARCHAR(255) PKSkroutz order code (natural key, not auto-increment)
stateENUMopen, accepted, rejected, cancelled, expired, dispatched, delivered, partially_returned, returned
invoiceTINYINT(1)Invoice requested flag
commentsVARCHAR(255)Customer order comments
courierVARCHAR(255)Assigned courier name
courier_voucherVARCHAR(255)Courier voucher number
courier_tracking_codesVARCHAR(255)Serialized tracking codes array
created_atDATETIMEOrder creation on Skroutz
expires_atDATETIMEAcceptance deadline
dispatch_untilDATETIMEDispatch deadline
number_of_parcelsVARCHAR(500)Comma-separated parcel count options
pickup_locationTEXTJSON pickup location options
pickup_windowTEXTJSON pickup time window options
reject_optionsTEXTJSON rejection reason options
customer_idVARCHAR(50)Skroutz customer ID
first_nameVARCHAR(50)Customer first name
last_nameVARCHAR(50)Customer last name
street_nameVARCHAR(255)Delivery street (null if collection point)
street_numberVARCHAR(10)Delivery street number
zipVARCHAR(10)Postal code
cityVARCHAR(100)City
regionVARCHAR(100)Region
pickup_from_collection_pointTINYINT(1)Collection point delivery flag
collection_point_addressVARCHAR(500)Collection point address
number_of_parcels_selectedINT(11)Admin-selected parcel count
pickup_window_selectedVARCHAR(250)Admin-selected pickup window
pickup_location_selectedVARCHAR(250)Admin-selected pickup location
shop_order_idINT(11) NULLFK to shop_order.id (set after acceptance)
expressTINYINT(1)Express delivery flag (auto-accept trigger)

skroutz_line_items Table ​

ColumnTypeDescription
idINT(11) PK AILine item ID
skroutz_idVARCHAR(255)Skroutz product ID
shop_uidVARCHAR(255)Shop product UID for matching
product_nameVARCHAR(255)Product display name
quantityINT(11)Ordered quantity
size_label / size_value / size_shop_valueVARCHAR(50)Size attribute data
unit_priceDECIMAL(11,2)Per-unit price
total_priceDECIMAL(11,2)Line total
price_includes_vatTINYINT(1)VAT inclusion flag
eanVARCHAR(255)Product EAN barcode
extra_infoVARCHAR(255)Additional product info
skroutz_order_codeVARCHAR(255)FK to skroutz_orders.code

skroutz_invoice_details Table ​

ColumnTypeDescription
idINT(11) PK AIRecord ID
companyVARCHAR(100)Company name
professionVARCHAR(100)Profession
vat_numberVARCHAR(9)Tax ID (AFM)
doyVARCHAR(100)Tax office
street_name / street_number / zip / city / regionVARCHARInvoice address
vat_exclusion_requestedTINYINT(1)VAT exemption requested
vat_exl_rep_*VARCHARVAT exclusion representative ID data
skroutz_order_codeVARCHAR(255)FK to skroutz_orders.code

shopflix_orders Table ​

ColumnTypeDescription
order_idINT(11) PKShopflix order ID (natural key)
order_referenceVARCHAR(255)Shopflix order reference
statusVARCHAR(50)Shopflix status code
payment_methodVARCHAR(50)Payment method
gift_wrapperTINYINT(1)Gift wrap flag
b_firstname / b_lastname / b_address / b_city / b_state / b_zipcode / b_country / b_phoneVARCHARBilling address
timestamp / last_order_changeVARCHAR(30)Order timestamps
voucher_creation_datetimeDATETIMEVoucher creation time
email / phoneVARCHARContact details
total / subtotal / discount / subtotal_discount / display_subtotalDECIMAL(10,2)Price breakdown
shippingVARCHAR(255)Shipping method
shipment_idsVARCHAR(255)Shipment tracking IDs
shopflix_vouchersVARCHAR(255)JSON voucher data
shipping_cost / display_shipping_costDECIMAL(10,2)Shipping costs
shop_order_idVARCHAR(255)FK to shop_order.id (set after acceptance)

shopflix_line_items Table ​

ColumnTypeDescription
idINT(11) PK AILine item ID
shop_uidINT(11)Shop product UID
shopflix_order_idVARCHAR(255)FK to shopflix_orders.order_id
product_id / product_code / productVARCHAR(255)Product identifiers and name
amountINT(11)Quantity
base_price / original_price / total_priceDECIMAL(10,2)Price data
eanVARCHAR(255)Product EAN
master_product_codeVARCHAR(255)Parent product code
product_status / status_a39VARCHAR(50)Status fields
item_idINT(11)Shopflix item ID
delivery_date / pickup_dateDATELogistics dates
product_urlVARCHAR(255)Product URL

public_orders Table ​

ColumnTypeDescription
order_idVARCHAR(255) PKPublic/Mirakl order ID (natural key)
stateENUMSame states as Skroutz
invoiceTINYINT(1)Invoice flag
is_tracking_sentTINYINT(1)Tracking sent to marketplace
is_sentTINYINT(1)Order dispatched flag
can_cancelTINYINT(1)Cancellable flag
order_dateDATETIMEOriginal order date
has_invoiceTINYINT(1)Invoice exists flag
shipping_deadline / acceptance_until_dateDATETIMEDeadline timestamps
shipping_price / total_price / commission_priceDECIMAL(10,2)Price data
order_typeVARCHAR(255)Order type classification
customer_id / first_name / last_name / email / region / commentsVARCHARCustomer data
shop_order_idINT(11)FK to shop_order.id (set after acceptance)

public_line_items Table ​

ColumnTypeDescription
idINT(11) PK AILine item ID
public_order_idVARCHAR(255)FK to public_orders.order_id
order_line_idVARCHAR(255)Mirakl line ID
product_nameVARCHAR(255)Product name
quantityINT(11)Quantity
unit_price / total_priceDECIMAL(11,2)Prices
eanVARCHAR(255)Product EAN

public_transporters_mapping Table ​

ColumnTypeDescription
transporter_idINT(11) PKInternal transporter FK
codeVARCHAR(255) PKPublic marketplace courier code

Maps Public/Mirakl courier codes to internal transporter IDs for voucher creation.

iris_orders Table ​

ColumnTypeDescription
idINT(11) PK AIRecord ID
messageIdVARCHAR(35)IRIS message ID
initiatingPartyRefIdVARCHAR(35)Initiating party reference
irisOrderIdVARCHAR(64)IRIS payment order ID
shop_order_idINT(11) NULLFK to shop_order.id
gift_card_orders_idINT(11) NULLFK to gift card orders table

jcc_order_ids Table ​

ColumnTypeDescription
idINT(11) PK AIRecord ID
jcc_order_idVARCHAR(255)JCC payment order ID
shop_order_idINT(11)FK to shop_order.id

Admin Controller Details ​

Adv_skroutz_orders_admin.php ​

The Skroutz admin controller handles order listing, acceptance, and rejection only. It has 4 methods:

MethodDescription
index()Paginated listing with filters (state, courier, pickup location)
resetIndex()Clear session filters
accept($code)Accept order: validate stock, call Skroutz API, create internal order
reject($code)Reject order: per-line-item rejection with reason codes via Skroutz API

Note: Voucher operations for Skroutz orders (create, cancel, print vouchers; manifests) are handled via the main Adv_orders_admin controller, not the Skroutz-specific controller.

Skroutz-specific batch actions (via overridden doBatchActionsSystem()):

  • accept_orders -- Batch accept multiple Skroutz orders
  • reject_orders -- Batch reject multiple Skroutz orders
  • mass_create_vouchers -- Batch voucher generation
  • mass_cancel_vouchers -- Batch voucher cancellation
  • mass_print_vouchers -- Batch voucher printing
  • get_manifest -- Get pickup manifest

Skroutz-specific features:

  • Pickup location selection from accepted orders (getAllSkroutzPickupLocationsFromOrders())
  • Courier filtering from order data (getAllSkroutzCouriersFromOrders())
  • Express order auto-acceptance when express=true
  • Auto-cleanup of orders 5+ days old without shop_order_id

Adv_shopflix_orders_admin.php ​

MethodDescription
index()Paginated listing
resetIndex()Clear filters
accept($code)Accept order via Shopflix API + create internal order
reject($code)Reject order via Shopflix API
createOrderVouchers($code)Generate vouchers
canceOrderlVouchers($code)Cancel vouchers
printVoucher($voucher)Print voucher
massPrintVouchers($orders)Batch print
massCreateVouchers($orders)Batch create vouchers
massCancelVouchers($orders)Batch cancel vouchers
getManifest($orders)Get manifest
getManifestByDate()Get manifest by date

Adv_public_orders_admin.php ​

MethodDescription
index()Paginated listing with state filter
processFilters()Filter processing for state/date
resetIndex()Clear filters
accept($orderId)Accept: validate stock, create internal order, call Public API
reject($orderId)Reject via Public/Mirakl API
transformTransportersData()Map internal transporters to Public marketplace codes

Public-specific validation: isValidOrder(), extractProductIds(), getLiveProductsParsed(), checkProductStock() -- validates each line item against live inventory before acceptance.