Appearance
eMAG Marketplace Feed
Flow ID: IN-05 | Module(s): feeds | Complexity: Low Last Updated: 2026-04-04
Business Overview
eMAG is a Romanian/Central European e-commerce marketplace. Unlike the Shopflix and Public integrations which include full order management, the eMAG integration is outbound product feed only -- there is no order reception or synchronization. The feed generates an XML product catalog that eMAG ingests to list products on their marketplace. The feed has several unique characteristics: negative-stock products are excluded entirely, numeric values are not wrapped in CDATA, prices are exported as net (without VAT), and descriptions are truncated to 250 characters.
API Reference
This integration does not use an API client. It exposes a single XML feed endpoint:
| Route | Controller | Purpose |
|---|---|---|
/xml/emag | AdvEmagXml::index() | Product catalog XML feed |
Authentication: Optional token-based protection via XML_FEEDS.EMAG_TOKEN query parameter.
Code Flow
Feed Generation
Entry point: AdvEmagXml::index()
AdvEmagXml::index()
|-- secureXml()
| |-- Check XML_FEEDS.IS_ENABLED_EMAG
| |-- If IS_PROTECTED_EMAG, validate ?token= against EMAG_TOKEN
|-- getProductData()
| |-- product_model::getFeedProductsForEmag()
| | |-- Calls getFeedProducts(XML_FEEDS['EMAG']) with feed ID 13
| |-- getLiveProductsParsed() for real-time stock/price
| |-- mergeDataToProduct() for each product
|-- parseForXml() inherited from AdvXml
| |-- parseItems() -> parseItem() per product
| |-- SKIP if availabilityStock < 0 (negative stock)
| |-- SKIP if no main image
| |-- Build item: Category, ID, Product_Name, Description, etc.
| |-- Net_Price = price_without_vat (+ modifier if CUSTOM_PRICE_EMAG)
|-- OutputEmagXml::createXml()
|-- Wraps in <Products><product>...</product></Products>
|-- Numeric values: raw (no CDATA)
|-- String values: wrapped in CDATAXML Element Mapping
| Element | Source | Notes |
|---|---|---|
Category | Category breadcrumb | » replaced with > |
ID | product->{xmlDbIdKey['emag']} | Configured product ID field |
Product_Name | skroutz_name or name | XML-sanitized |
Description | description or skroutz_name | Truncated to 250 chars, HTML stripped |
Product_link | site_url(productUrl) | Full product URL |
EAN | barcode | EAN/barcode |
Stock | availabilityStock | Real-time stock count |
Pictures_link | Main product image URL | Full asset URL |
Brand | vendor_name | Manufacturer/brand |
Net_Price | price_without_vat | Price excluding VAT; optionally modified |
Price Modifier
When XML_FEEDS.CUSTOM_PRICE_EMAG is enabled, the net price is adjusted:
Net_Price = price_without_vat + round(price_without_vat * priceModifier / 100, 2)The priceModifier is a per-product percentage stored via the feed price modifier system (managed in Settings > XML Feeds).
Architecture
ecommercen/feeds/controllers/AdvEmagXml.php -- Feed controller (extends AdvXml)
ecommercen/feeds/core/AdvXml.php -- Base XML feed class (extends Base_c)
src/Feeds/Output/OutputEmagXml.php -- XML output formatter (overrides addItem for CDATA logic)
src/Feeds/Output/OutputGenericXml.php -- Base XML output class
src/Feeds/Output/OutputXmlConfig.php -- Config VO (collectionName='Products', collectionItemName='product')
src/Feeds/Feed.php -- Feed orchestratorInheritance chain: AdvEmagXml extends AdvXml (base feed controller) extends Base_c (CI front controller). The OutputEmagXml class extends OutputGenericXml and overrides the addItem() method to conditionally apply CDATA wrapping based on value type.
Data Model
This integration does not have its own database tables. It reads from the standard product tables through the feed product query system:
| Source | Purpose |
|---|---|
shop_product + shop_product_mui | Product master data |
product_codes | SKU/barcode data |
shop_product_barcodes | EAN codes |
shop_product_category_mui | Category breadcrumbs |
shop_product_feed | Feed assignment (feed ID = 13 for eMAG) |
shop_product_feed_lp | Per-product price modifiers |
The feed ID constant is defined in application/config/constants.php:
php
'EMAG' => 13Configuration
Registry Keys (XML_FEEDS group)
| Key | Type | Purpose |
|---|---|---|
IS_ENABLED_EMAG | int | Enable/disable the eMAG feed |
IS_PROTECTED_EMAG | bool | Require token authentication |
EMAG_TOKEN | string | Authentication token (auto-generated if missing) |
CUSTOM_PRICE_EMAG | bool | Enable custom price modifier |
CUSTOM_PRICE_EMAG_MODIFIER | float | Global price modifier percentage |
Product ID Key
The product identifier field is configured in application/config/app.php under xmlDbIdKey['emag']. This determines which product field maps to the <ID> XML element.
Feed URL
https://{domain}/xml/emag?token={EMAG_TOKEN}Supports language prefix: /{lang}/xml/emag?token={EMAG_TOKEN}
Client Extension Points
- Feed controller override: Create
application/controllers/Xml.phpwith customemag()method routing - Custom price modifiers: Per-product via admin product feed settings
- Feed product assignment: Products must be assigned to feed ID 13 (eMAG) to appear
- Product ID field: Configurable via
xmlDbIdKey['emag']in app config - Description source: Falls back from
descriptiontoskroutz_name
Business Rules
| Rule | Description |
|---|---|
| No negative stock | Products with availabilityStock < 0 are excluded entirely (not zero-stocked) |
| No image = excluded | Products without a main image are skipped |
| 250 char description | Description truncated to 250 characters after HTML stripping |
| Net price (no VAT) | Net_Price field exports price_without_vat, not the retail price |
| Numeric = no CDATA | Numeric fields rendered as raw values; strings get CDATA wrapping |
| Feed-only integration | No order sync, no webhooks, no background jobs |
| Token auto-generation | If EMAG_TOKEN is not set, a unique token is auto-generated on first settings save |
| Custom price additive | Price modifier adds a percentage to base price (not multiplicative) |
Related Flows
- IN-01 Feed Generation -- shared feed architecture and product query system
- AD-11 Marketplace Orders -- comparison with order-enabled marketplaces