Send Discord webhook notifications on Medusa store events with dynamic settings.
A Discord webhook notification plugin for Medusa v2. Route store events to your Discord channels with rich embed cards that automatically update in-place as order status changes — from placed → fulfilled → shipped → completed or canceled.
yarn add @sam-ael/medusa-plugin-discord1import { DiscordNotificationOptions } from "@sam-ael/medusa-plugin-discord/modules/discord-notification"2
3plugins: [4 {5 resolve: "@sam-ael/medusa-plugin-discord",6 options: {7 // Global fallback bot name. Can also be set via env var (see below).8 // Per-mapping bot names set in the Admin UI take priority over this.9 defaultBotName: process.env.DISCORD_DEFAULT_BOT_NAME || "Discord Bot",10 } satisfies DiscordNotificationOptions,11 },12],1# .env2DISCORD_DEFAULT_BOT_NAME="My Store Bot"npx medusa db:migrateNavigate to Settings → Discord Notifications in the Medusa Admin panel.
| Field | Required | Description |
|---|---|---|
| Event Trigger | ✅ | Which Medusa event fires this webhook |
| Discord Webhook URL | ✅ | Full Discord webhook URL |
| Channel Label | ❌ | Friendly label (e.g. ) — display only |
| Bot Name | ❌ | Override the bot's display name for this channel. Falls back to plugin option → |
| Custom Message Template | ❌ | Discord Markdown template. Leave blank for default rich embed. |
| Enabled | ✅ | Toggle to activate/deactivate without deleting |
The plugin stores the Discord returned when an order notification is first posted. All subsequent events for the same order edit that same message rather than posting new ones.
1order.placed → POST new message → message_id saved to DB2order.fulfillment_created → PATCH same message → status updated to "Fulfillment Created 📦"3fulfillment.shipment_created → PATCH same message → status + tracking links shown 🚚4order.completed → PATCH same message → status "Completed ✅" (green)5order.canceled → PATCH same message → status "Canceled 🔴" (red)If the original Discord message is manually deleted, the plugin automatically posts a fresh message and saves the new .
| Event | Description |
|---|---|
| New order placed | |
| Fulfillment created for an order | |
| Shipment created with tracking info | |
| Order marked as completed | |
| Order canceled | |
| Order updated | |
| New customer registered | |
| Customer profile updated |
| Placeholder | Description |
|---|---|
| Order ID | |
| Human-readable order number | |
| Order status | |
| Order total (formatted as decimal) | |
| Subtotal (formatted as decimal) | |
| Currency code (e.g. ) | |
| Customer email | |
| Payment status | |
| Fulfillment status | |
| , , or | |
| Comma-separated tracking numbers | |
| Tracking numbers as clickable Discord markdown links | |
| Shipping first name | |
| Shipping last name | |
| Shipping city | |
| Customer account email |
| Placeholder | Description |
|---|---|
| Customer ID | |
| Email address | |
| First name | |
| Last name | |
| Phone number |
1type DiscordNotificationOptions = {2 /**3 * Global fallback bot username shown in Discord when no4 * per-mapping bot_name is configured in the Admin UI.5 * Defaults to "Discord Bot".6 */7 defaultBotName?: string8}| Method | Endpoint | Description |
|---|---|---|
| List all webhook mappings | ||
| Create a new webhook mapping | ||
| Update a webhook mapping | ||
| Delete a webhook mapping | ||
| Send a test notification using mock data |
1{2 "event_name": "order.placed",3 "webhook_url": "https://discord.com/api/webhooks/...",4 "channel_name": "#orders",5 "bot_name": "Enchauntee Sales Bot",6 "is_active": true,7 "message_template": "📦 New order **#{display_id}** from **{email}** — **{total} {currency_code}**"8}1yarn typecheck2yarn buildMIT