shipmondo
v1.2.1
Published
Medusa v2 plugin for Shipmondo — sales orders, shipments, shipping labels, fulfillment automation, webhook-driven tracking, and service point selection
Maintainers
Readme
shipmondo
A Medusa v2 plugin that integrates Shipmondo for shipping management — sales orders, shipments with tracking, shipping labels, fulfillment automation, service point selection, and webhook-driven state sync.
Features
- Sales Order Sync — Push Medusa orders to Shipmondo as sales orders
- Fulfillment Automation — Creating a Medusa fulfillment creates a Shipmondo fulfillment; Shipmondo-originated fulfillments are mirrored back into Medusa via webhooks
- Shipments & Tracking — Shipments created in Shipmondo are linked to Medusa fulfillments with tracking numbers and tracking URLs
- Shipping Labels — Download labels as PDF directly from the admin
- Delivery State — Shipment Monitor
deliveredwebhook marks Medusa fulfillments as delivered - Service Point Selection — Let customers pick a pickup location during checkout
- Retry Failed Shipments — Retry shipment creation from the admin when something goes wrong
- Sandbox & Production — Switch between Shipmondo sandbox and production environments
Prerequisites
- Medusa v2 (
@medusajs/medusa ^2.13.5) - Node.js
>=20 - A Shipmondo account with API credentials
Installation
npm install shipmondoConfiguration
Add the following environment variables:
SHIPMONDO_API_USERNAME=your_api_username
SHIPMONDO_API_KEY=your_api_key
SHIPMONDO_ENVIRONMENT=sandbox # or "production"
SHIPMONDO_WEBHOOK_KEY=your_hmac_key # required for webhook-driven flowsThen register the module and fulfillment provider in your medusa-config.js:
const {
SHIPMONDO_API_USERNAME,
SHIPMONDO_API_KEY,
SHIPMONDO_ENVIRONMENT,
SHIPMONDO_WEBHOOK_KEY,
} = process.env
module.exports = defineConfig({
// ...
modules: [
{
key: "shipmondo",
resolve: "shipmondo/modules/shipmondo",
options: {
api_username: SHIPMONDO_API_USERNAME,
api_key: SHIPMONDO_API_KEY,
environment: SHIPMONDO_ENVIRONMENT || "sandbox",
webhook_key: SHIPMONDO_WEBHOOK_KEY,
},
},
],
providers: [
{
resolve: "shipmondo/providers/shipmondo-fulfillment",
id: "shipmondo",
options: {
api_username: SHIPMONDO_API_USERNAME,
api_key: SHIPMONDO_API_KEY,
environment: SHIPMONDO_ENVIRONMENT || "sandbox",
},
},
],
})Run migrations after installing:
npx medusa db:migrateHow It Works
Sales Orders
Sales orders are the Shipmondo representation of a Medusa order. Create one via the admin API before fulfilling:
POST /admin/shipmondo/sales-orders
{ "order_id": "order_abc123" }The plugin transforms the Medusa order (items, addresses, payment) into a Shipmondo sales order and syncs it. The Shipmondo sales order ID is stored in the Medusa order's metadata for downstream workflows.
Shipments & Fulfillments
There are two directions of sync:
- Medusa → Shipmondo — Creating a Medusa fulfillment with the Shipmondo provider creates a corresponding Shipmondo fulfillment under the synced sales order.
- Shipmondo → Medusa — When a shipment is created in Shipmondo (e.g. from the Shipmondo dashboard or bulk label printing), the
Orders/create_shipmentwebhook triggers a workflow that links the shipment to the matching Medusa fulfillment and stores the tracking number and tracking URL.
If shipment creation fails, a record is stored with sync_status: "failed" and can be retried:
POST /admin/shipmondo/shipments/retry
{ "fulfillment_id": "ful_abc123" }Shipping Labels
Download labels for a fulfillment or a specific shipment:
GET /admin/shipmondo/fulfillments/:fulfillment_id/label
GET /admin/shipmondo/labels/:idBoth return a PDF file.
Webhooks
Point Shipmondo's webhook configuration at:
POST https://your-medusa-host/shipmondo/webhookUse the same HMAC key in both the Shipmondo admin and SHIPMONDO_WEBHOOK_KEY. Supported events:
| Resource | Action | Effect |
|----------|--------|--------|
| Orders | create_fulfillment | Mirrors the Shipmondo fulfillment into Medusa |
| Orders | create_shipment | Links the shipment to the Medusa fulfillment and stores tracking data |
| Shipment Monitor | delivered | Marks the Medusa fulfillment as delivered |
Unknown events are logged and acknowledged with 200 OK so Shipmondo does not retry.
Service Points (Pickup Locations)
For carriers that support pickup locations (e.g. GLS, PostNord), customers can select a service point during checkout:
1. Search for nearby service points:
GET /store/shipmondo/service-points?product_code=GLSDK_SHOP&country_code=DK&zipcode=21002. Select a service point for the cart:
POST /store/shipmondo/service-points/select
{
"cart_id": "cart_abc123",
"service_point_id": "12345",
"carrier_code": "gls",
"service_point_name": "Kiosk",
"service_point_address": "Main St 1",
"service_point_zipcode": "2100",
"service_point_city": "Copenhagen",
"service_point_country_code": "DK"
}The selected service point is stored in the cart metadata and carried over to the order when checkout completes.
API Reference
Admin Routes
| Method | Route | Description |
|--------|-------|-------------|
| POST | /admin/shipmondo/sales-orders | Create a sales order from a Medusa order |
| GET | /admin/shipmondo/sales-orders?order_id= | List sales orders for an order |
| GET | /admin/shipmondo/shipments?fulfillment_id= | List shipments for a fulfillment |
| POST | /admin/shipmondo/shipments/retry | Retry a failed shipment creation |
| GET | /admin/shipmondo/fulfillments/:fulfillment_id/label | Download label PDF for a fulfillment |
| GET | /admin/shipmondo/labels/:id | Download label PDF by shipment ID |
Store Routes
| Method | Route | Description |
|--------|-------|-------------|
| GET | /store/shipmondo/service-points | Search for service points |
| POST | /store/shipmondo/service-points/select | Select a service point for a cart |
Webhook Route
| Method | Route | Description |
|--------|-------|-------------|
| POST | /shipmondo/webhook | Shipmondo webhook receiver (HMAC-verified) |
Exports
The plugin exports the following for use in custom workflows or extensions:
import {
shipmondoModule,
SHIPMONDO_MODULE,
ShipmondoModuleService,
shipmondoFulfillmentProvider,
createShipmondoSalesOrderWorkflow,
handleShipmondoFulfillmentCreatedWorkflow,
handleShipmondoShipmentCreatedWorkflow,
handleShipmondoShipmentDeliveredWorkflow,
} from "shipmondo"
import type {
ShipmondoModuleOptions,
SyncStatus,
ShipmondoClientOptions,
} from "shipmondo"Database
The plugin creates two tables:
shipmondo_sales_order— Tracks synced sales orders (shipmondo_id,order_id,sync_status)shipmondo_shipment— Tracks shipments (shipmondo_id,fulfillment_id,tracking_number, label data,sync_status)
Both tables support soft deletes, are indexed on the lookup columns, and store the raw Shipmondo API response for debugging.
Development
# Install dependencies
npm install
# Build the plugin
npm run buildSmoke Test
Verify your API credentials against the Shipmondo sandbox:
SHIPMONDO_API_USERNAME=user SHIPMONDO_API_KEY=key \
npx ts-node src/__tests__/smoke-test.tsLicense
MIT
