The ERPNext Medusa Integration keeps your product catalog in sync by pushing Website Item data from ERPNext to Medusa automatically. This page explains the full sync lifecycle: which fields are mapped, how product variants and collections are created, how to trigger a bulk export, and how to skip updates when needed.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/aerele/medusa_integration/llms.txt
Use this file to discover all available pages before exploring further.
How sync is triggered
Every time a Website Item is saved, thewebsite_item_validate hook fires. It checks whether the item already has a medusa_id:
- If
medusa_idis empty → callsexport_website_item()to create a new Medusa product. - If
medusa_idis set → callsupdate_website_item()to push changes to the existing Medusa product.
hooks.py:
Field mapping
The following ERPNext fields are mapped to Medusa product fields when callingPOST /admin/products:
| ERPNext field | Medusa field | Notes |
|---|---|---|
web_item_name | title | Display name on storefront |
item_code | item_code | Custom field on Medusa product |
web_long_description | description | HTML stripped via strip_html() + html.unescape() |
short_description | short_description | Plain text |
ranking | ranking | Numeric sort order |
published | status | True → "published", False → "draft" |
brand | brand_name | Brand name string |
country_of_origin (from Item) | origin_country | Resolved to ISO country code (uppercase) |
website_specifications | specifications | Array of {label, description} objects; HTML stripped |
item_group → collection | collection_id | Item Group is exported as a Medusa collection first |
stock_uom | metadata.UOM | Stored in product metadata |
Example payload
Product variants
Each Website Item gets exactly one Medusa variant — a “Default” variant. Variants are created immediately after the product is created, viacreate_medusa_variant().
The variant is configured with:
manage_inventory: true— Medusa tracks stock levels for this variant.allow_backorder— set totrueif the Website Item hason_backorderchecked,falseotherwise.inventory_quantity: 0— initial quantity; stock is synced separately by the scheduled task.
medusa_variant_id. This field is used throughout the integration (order creation, inventory sync, price lists) to reference the correct Medusa variant.
Item Groups as Medusa collections
Before a product can be exported, its Item Group must exist in Medusa as a collection. Theexport_item_group() function handles this:
export_website_item() calls export_item_group() automatically if item_group.medusa_id is empty. The collection ID is then included in the product payload as collection_id.
Bulk export
There are two ways to export all Website Items that do not yet have amedusa_id.
- Simple bulk export
- Batched parallel export
export_all_website_item() iterates over all published Website Items without a medusa_id and exports them one by one. Errors are caught per item and logged.Skipping updates
Some operations (such as adding a review or updating a wishlist) save the Website Item internally without intending to push changes to Medusa. To prevent a spurious update, these operations set thecustom_skip_update_hook flag to 1 before saving:
update_website_item() checks this flag at the start of every call:
Deleting products
When a Website Item is trashed, theon_trash hook calls delete_medusa_item(), which sends a DELETE /admin/products/{medusa_id} request to remove the product from Medusa.
Scheduled tasks
| Schedule | Function | Purpose |
|---|---|---|
0 1 * * * (daily at 1 AM) | export_items_and_images_custom() | Bulk export any unsynced published items in 4 parallel batches |