Medusa v2 plugin for Contífico ERP integration — product & stock sync, customer mapping, weighted pricing strategies, and automated electronic invoicing for Ecuador.
- Product synchronization — import products and categories from Contífico, with automatic variant creation.
- Stock synchronization — real-time inventory levels from Contífico warehouses (
bodegas). - Customer mapping — match and sync customers between Medusa and Contífico.
- Weighted pricing — pluggable strategies for weight-based product pricing (e.g., products sold by weight in grams/kg).
- Electronic invoicing — automatic creation of pre-invoices (
PRE) on order placement and invoices (FAC) on payment capture. - Admin UI — full dashboard for configuration, diagnostics, sync triggers, invoice previews, and linked product management.
- Observability — correlation IDs, structured logs, and sync audit trail.
| Requirement | Version |
|---|---|
| Node.js | >= 20 |
| Medusa | >= 2.13.3 (built and tested against 2.21.2) |
| Contífico account | API key required |
npm install @codemind.ec/medusa-plugin-contifico
# or
pnpm add @codemind.ec/medusa-plugin-contificoAdd the plugin and its module to your medusa-config.ts:
import { defineConfig } from "@medusajs/framework/utils"
export default defineConfig({
// ...
modules: [
{
resolve: "@codemind.ec/medusa-plugin-contifico/contifico",
definition: { isQueryable: true },
},
],
plugins: [
{
resolve: "@codemind.ec/medusa-plugin-contifico",
options: {},
},
],
})Nota: El módulo se registra por separado en
modules[]conisQueryable: truepara que sea accesible desde el query graph de Medusa. La entrada enplugins[]carga admin UI, API routes, subscribers y links.
| Variable | Required | Description |
|---|---|---|
CONTIFICO_API_KEY |
Yes | Contífico API key |
CONTIFICO_API_POS |
For invoicing | Point-of-sale identifier for FAC / PRE |
CONTIFICO_URL |
No | API base URL (default: https://api.contifico.com) |
The plugin registers a single module with three database models:
| Field | Type | Description |
|---|---|---|
api_key |
string | Contífico API key |
api_pos |
string | Point-of-sale ID |
bodega_ids |
string | Comma-separated warehouse IDs |
sync_products_enabled |
boolean | Enable product sync |
sync_customers_enabled |
boolean | Enable customer sync |
auto_invoice_enabled |
boolean | Auto-create FAC on payment capture |
auto_preinvoice_enabled |
boolean | Auto-create PRE on order placed |
sync_interval_minutes |
number | Sync frequency (default: 60) |
variant_mode |
enum | "auto" | "contifico" | "simple" | "weighted" |
weighted_pvp_field |
enum | "pvp1" | "pvp2" | "pvp3" | "pvp4" |
advanced_settings |
JSON | Versioned configuration (v2) |
import_filters |
JSON | Product import filters |
invoice_test_mode |
boolean | Test mode for invoicing |
| Field | Type | Description |
|---|---|---|
entity_type |
enum | product | variant | customer | category | invoice |
medusa_id |
string | Medusa entity ID (or typed key like order_id:FAC) |
contifico_id |
string | Contífico entity ID |
metadata |
JSON? | Extra mapping data |
| Field | Type | Description |
|---|---|---|
sync_type |
enum | products | stock | customers | invoice |
status |
enum | queued | running | success | partial | error | cancelled |
phase |
string? | Current phase description |
progress_percent |
number? | Progress 0–100 |
duration_ms |
number? | Total duration |
total_processed |
number? | Items processed |
total_errors |
number? | Error count |
details |
JSON? | Detailed results |
correlation_id |
string? | Correlation ID for tracing |
The plugin includes a purpose-built HTTP client with:
- Automatic retry with exponential backoff
- Request timeout (15s default)
- SSRF protection — blocks private IP ranges
Sub-clients:
| Client | Scope |
|---|---|
ContificoProductsClient |
Product & category CRUD |
ContificoInvoicesClient |
Create, query, cancel documents |
ContificoCustomersClient |
Search & create customers |
ContificoInventoryClient |
Stock lookups |
The plugin supports pluggable pricing strategies for weight-based products:
| Strategy | Description |
|---|---|
fixed_pvp_field |
Uses a fixed PVP field (pvp1–pvp4) for all products |
rules_by_weight |
Calculates PVP based on weight range rules (e.g., 100–250g, 250–500g) |
Price resolution precedence:
- Per-product override (
product.metadata.weighted_pvp_field) - Active weighted strategy
- Fallback field from strategy defaults
Strategies implement the WeightedPriceStrategy interface:
interface WeightedPriceStrategy {
id: string
label: string
description: string
capabilities: {
uses_fixed_field?: boolean
uses_weight_rules?: boolean
supports_price_lock?: boolean
}
defaultConfig: object
normalizeConfig(config: unknown): object
validate(config: unknown): ValidationResult
resolvePriceField(product: any, context: any): string | number
explain(product: any, context: any): string
}The admin UI uses declarative dependency gates to show/hide/disable fields based on configuration state:
| Gate | Visible When | Enabled When |
|---|---|---|
weighted_strategy |
variant_mode === "weighted" |
always |
weighted_price_lock |
sync_products enabled | strategy supports_price_lock |
auto_invoice |
always | api_pos configured |
sync_interval |
always | ≥ 1 automatic task active |
| Method | Endpoint | Description |
|---|---|---|
GET |
/admin/contifico/config |
Get current configuration |
POST |
/admin/contifico/config |
Create or update configuration |
POST |
/admin/contifico/config/check-connection |
Test API connection to Contífico |
GET |
/admin/contifico/config/bodegas |
List warehouses from Contífico |
| Method | Endpoint | Description |
|---|---|---|
POST |
/admin/contifico/sync/products |
Trigger product sync |
POST |
/admin/contifico/sync/products/preview |
Preview product sync (dry run) |
POST |
/admin/contifico/sync/products/stock |
Trigger stock sync |
POST |
/admin/contifico/sync/products/delete |
Delete imported products |
POST |
/admin/contifico/sync/products/delete/preview |
Preview product deletion (dry run) |
POST |
/admin/contifico/sync/customers |
Sync customers to Contífico |
GET |
/admin/contifico/sync-logs |
List recent sync logs |
| Method | Endpoint | Description |
|---|---|---|
GET |
/admin/contifico/products/linked |
List linked products (diagnostics) |
GET |
/admin/contifico/products/match |
Get product match recommendations |
POST |
/admin/contifico/products/link |
Create product link (Medusa ↔ Contífico) |
PUT |
/admin/contifico/products/link |
Re-link / update a product link |
DELETE |
/admin/contifico/products/link |
Remove a product link |
POST |
/admin/contifico/products/linked/migrate |
Migrate linked product metadata |
| Method | Endpoint | Description |
|---|---|---|
GET |
/admin/contifico/invoices |
List invoices |
POST |
/admin/contifico/invoices |
Create invoice or run test actions |
POST |
/admin/contifico/invoices/preview |
Preview invoice document (dry run) |
GET |
/admin/orders/:id/contifico-documents |
Get document status for an order |
POST |
/admin/orders/:id/contifico-documents |
Create / update order documents |
| Method | Endpoint | Description |
|---|---|---|
GET |
/admin/contifico/media |
Proxy Contífico product images |
| Method | Endpoint | Description |
|---|---|---|
GET |
/admin/plugin |
Plugin health check (admin) |
GET |
/store/plugin |
Plugin health check (store) |
| Event | Action |
|---|---|
CONTIFICO_PRODUCTS_SYNC_REQUESTED |
Runs product sync job |
CONTIFICO_PRODUCTS_STOCK_REQUESTED |
Runs stock sync job |
order.placed |
Creates PRE (if auto_preinvoice_enabled) |
payment.captured |
Creates FAC (if auto_invoice_enabled + api_pos) |
All automated operations use correlation_id for end-to-end tracing.
Documents use typed keys (order_id:PRE, order_id:FAC) to prevent duplicates. The system performs:
- Local deduplication — checks
contifico_entity_mapbefore creating. - Remote deduplication — queries Contífico API for existing documents.
- Race condition handling — if a remote duplicate is detected after creation, the local duplicate is cancelled defensively.
When invoice_test_mode is enabled, documents are created with prefix test:order_id:TYPE and can be bulk-deleted via deleteTestInvoiceDocuments().
pnpm testThe plugin includes a Vitest suite covering:
- Legacy → v2 config migration
- Weighted strategy registry
- Dependency gate evaluation
- Product sync pipeline
- PRE/FAC subscriber flows
MIT — CodeMind