order-management 0.0.8 → 0.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,166 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.config = void 0;
4
+ exports.default = sendOrderEmailHandler;
5
+ const utils_1 = require("@medusajs/framework/utils");
6
+ const resolve_options_1 = require("../utils/resolve-options");
7
+ const template_1 = require("../utils/template");
8
+ /**
9
+ * Prepare email payload for notification service
10
+ */
11
+ function prepareEmailPayload(to, subject, htmlContent) {
12
+ // Create plain text version from HTML
13
+ const textContent = htmlContent
14
+ .replace(/<[^>]*>/g, '') // Remove HTML tags
15
+ .replace(/\s+/g, ' ') // Collapse whitespace
16
+ .trim();
17
+ const payload = {
18
+ to,
19
+ channel: "email",
20
+ subject,
21
+ // Root level fields for SMTP providers
22
+ html: htmlContent,
23
+ text: textContent,
24
+ body: htmlContent, // Some providers expect 'body' field
25
+ template: htmlContent, // Some providers expect 'template' field
26
+ data: {
27
+ subject,
28
+ html: htmlContent,
29
+ text: textContent,
30
+ },
31
+ };
32
+ return payload;
33
+ }
34
+ /**
35
+ * Subscriber handler for order.placed event
36
+ * Sends email with order data when an order is placed (if template is configured)
37
+ */
38
+ async function sendOrderEmailHandler({ event: { data }, container, }) {
39
+ try {
40
+ // Check if email template is configured
41
+ let templatePath = null;
42
+ try {
43
+ const configModule = container.resolve(utils_1.ContainerRegistrationKeys.CONFIG_MODULE);
44
+ const pluginOptions = (0, resolve_options_1.extractOrderManagementOptions)(configModule);
45
+ const options = (0, resolve_options_1.resolveOrderManagementOptions)(pluginOptions);
46
+ templatePath = options.email.template;
47
+ if (!templatePath) {
48
+ console.log("[Order Email Subscriber] Email template path not configured, skipping email");
49
+ return;
50
+ }
51
+ }
52
+ catch (error) {
53
+ // If config resolution fails, skip email sending
54
+ console.debug("[Order Email Subscriber] Could not resolve config, skipping email");
55
+ return;
56
+ }
57
+ // Extract order ID from event data
58
+ const orderId = data.id;
59
+ if (!orderId) {
60
+ console.error("[Order Email Subscriber] No order ID found in event data");
61
+ return;
62
+ }
63
+ // Query order details if event only provides ID
64
+ // Check if data already has full order object
65
+ let orderData;
66
+ if (data.email && data.items) {
67
+ // Event already contains full order data
68
+ orderData = data;
69
+ }
70
+ else {
71
+ // Query order details using query service
72
+ const query = container.resolve(utils_1.ContainerRegistrationKeys.QUERY);
73
+ const { data: orders = [] } = await query.graph({
74
+ entity: "order",
75
+ fields: [
76
+ "id",
77
+ "status",
78
+ "total",
79
+ "grand_total",
80
+ "email",
81
+ "created_at",
82
+ "updated_at",
83
+ "items.*",
84
+ "shipping_address.*",
85
+ "billing_address.*",
86
+ ],
87
+ filters: { id: orderId },
88
+ });
89
+ const order = Array.isArray(orders) ? orders[0] : orders;
90
+ if (!order) {
91
+ console.error(`[Order Email Subscriber] Order with id ${orderId} not found`);
92
+ return;
93
+ }
94
+ orderData = order;
95
+ }
96
+ // Extract email from order data
97
+ const email = orderData.email;
98
+ if (!email || typeof email !== "string" || !email.includes("@")) {
99
+ console.error(`[Order Email Subscriber] No valid email found for order ${orderId}`);
100
+ return;
101
+ }
102
+ // Prepare template data
103
+ const totalValue = orderData.total || orderData.grand_total;
104
+ const orderTotal = typeof totalValue === "number"
105
+ ? totalValue
106
+ : typeof totalValue === "string"
107
+ ? totalValue
108
+ : "N/A";
109
+ const templateData = {
110
+ order_id: orderData.id || "N/A",
111
+ order_status: orderData.status || "N/A",
112
+ order_total: orderTotal,
113
+ order_email: orderData.email || "N/A",
114
+ order_date: (orderData.created_at || orderData.updated_at || new Date().toISOString()),
115
+ order_items: orderData.items || [],
116
+ shipping_address: orderData.shipping_address || {},
117
+ billing_address: orderData.billing_address || {},
118
+ };
119
+ // Load and render template
120
+ const renderedTemplate = (0, template_1.loadAndRenderTemplate)(templatePath, templateData);
121
+ if (!renderedTemplate) {
122
+ console.error(`[Order Email Subscriber] Failed to load or render template from ${templatePath}`);
123
+ return;
124
+ }
125
+ // Resolve notification service
126
+ const notificationService = container.resolve(utils_1.Modules.NOTIFICATION);
127
+ if (!notificationService) {
128
+ console.error("[Order Email Subscriber] Notification service is not configured");
129
+ return;
130
+ }
131
+ // Prepare email payload
132
+ const subject = "Order Confirmation";
133
+ const payload = prepareEmailPayload(email, subject, renderedTemplate);
134
+ // Send email
135
+ try {
136
+ if (typeof notificationService.createNotifications === "function") {
137
+ await notificationService.createNotifications([payload]);
138
+ console.log(`[Order Email Subscriber] Email sent successfully for order ${orderId}`);
139
+ }
140
+ else if (typeof notificationService.create === "function") {
141
+ await notificationService.create(payload);
142
+ console.log(`[Order Email Subscriber] Email sent successfully for order ${orderId}`);
143
+ }
144
+ else {
145
+ console.error("[Order Email Subscriber] Notification service does not support sending notifications");
146
+ }
147
+ }
148
+ catch (error) {
149
+ const errorMessage = error instanceof Error ? error.message : String(error);
150
+ console.error(`[Order Email Subscriber] Failed to send email for order ${orderId}:`, errorMessage);
151
+ // Don't throw - subscriber errors shouldn't break the order flow
152
+ }
153
+ }
154
+ catch (error) {
155
+ const errorMessage = error instanceof Error ? error.message : String(error);
156
+ console.error("[Order Email Subscriber] Error processing order email:", errorMessage);
157
+ // Don't throw - subscriber errors shouldn't break the order flow
158
+ }
159
+ }
160
+ /**
161
+ * Subscriber configuration
162
+ */
163
+ exports.config = {
164
+ event: "order.placed",
165
+ };
166
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VuZC1vcmRlci1lbWFpbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9zdWJzY3JpYmVycy9zZW5kLW9yZGVyLWVtYWlsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQWdFQSx3Q0FnSkM7QUEvTUQscURBQThFO0FBRTlFLDhEQUdpQztBQUNqQyxnREFBaUY7QUFPakY7O0dBRUc7QUFDSCxTQUFTLG1CQUFtQixDQUMxQixFQUFVLEVBQ1YsT0FBZSxFQUNmLFdBQW1CO0lBRW5CLHNDQUFzQztJQUN0QyxNQUFNLFdBQVcsR0FBRyxXQUFXO1NBQzVCLE9BQU8sQ0FBQyxVQUFVLEVBQUUsRUFBRSxDQUFDLENBQUMsbUJBQW1CO1NBQzNDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsc0JBQXNCO1NBQzNDLElBQUksRUFBRSxDQUFBO0lBRVQsTUFBTSxPQUFPLEdBYVQ7UUFDRixFQUFFO1FBQ0YsT0FBTyxFQUFFLE9BQU87UUFDaEIsT0FBTztRQUNQLHVDQUF1QztRQUN2QyxJQUFJLEVBQUUsV0FBVztRQUNqQixJQUFJLEVBQUUsV0FBVztRQUNqQixJQUFJLEVBQUUsV0FBVyxFQUFFLHFDQUFxQztRQUN4RCxRQUFRLEVBQUUsV0FBVyxFQUFFLHlDQUF5QztRQUNoRSxJQUFJLEVBQUU7WUFDSixPQUFPO1lBQ1AsSUFBSSxFQUFFLFdBQVc7WUFDakIsSUFBSSxFQUFFLFdBQVc7U0FDbEI7S0FDRixDQUFBO0lBRUQsT0FBTyxPQUFPLENBQUE7QUFDaEIsQ0FBQztBQUVEOzs7R0FHRztBQUNZLEtBQUssVUFBVSxxQkFBcUIsQ0FBQyxFQUNsRCxLQUFLLEVBQUUsRUFBRSxJQUFJLEVBQUUsRUFDZixTQUFTLEdBQzRCO0lBQ3JDLElBQUksQ0FBQztRQUNILHdDQUF3QztRQUN4QyxJQUFJLFlBQVksR0FBa0IsSUFBSSxDQUFBO1FBQ3RDLElBQUksQ0FBQztZQUNILE1BQU0sWUFBWSxHQUFHLFNBQVMsQ0FB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
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3JkZXItbWFuYWdlbWVudC1vcHRpb25zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3R5cGVzL29yZGVyLW1hbmFnZW1lbnQtb3B0aW9ucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIn0=
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveOrderManagementOptions = resolveOrderManagementOptions;
4
+ exports.extractOrderManagementOptions = extractOrderManagementOptions;
5
+ const DEFAULT_OPTIONS = {
6
+ email: {
7
+ template: null,
8
+ },
9
+ };
10
+ /**
11
+ * Resolve and normalize plugin options with defaults
12
+ */
13
+ function resolveOrderManagementOptions(options) {
14
+ if (!options) {
15
+ return DEFAULT_OPTIONS;
16
+ }
17
+ return {
18
+ email: {
19
+ template: options.email?.template ?? DEFAULT_OPTIONS.email.template,
20
+ },
21
+ };
22
+ }
23
+ /**
24
+ * Extract plugin options from config module
25
+ */
26
+ function extractOrderManagementOptions(configModule) {
27
+ // Try from projectConfig.plugins first
28
+ const plugins = configModule?.projectConfig?.plugins ?? [];
29
+ for (const plugin of plugins) {
30
+ if (typeof plugin === "string") {
31
+ if (plugin === "order-management") {
32
+ return {};
33
+ }
34
+ continue;
35
+ }
36
+ if (plugin?.resolve === "order-management") {
37
+ return plugin.options;
38
+ }
39
+ }
40
+ // Try from direct config.plugins (fallback)
41
+ const directPlugins = configModule?.plugins ?? [];
42
+ for (const plugin of directPlugins) {
43
+ if (typeof plugin === "string") {
44
+ if (plugin === "order-management") {
45
+ return {};
46
+ }
47
+ continue;
48
+ }
49
+ if (plugin?.resolve === "order-management") {
50
+ return plugin.options;
51
+ }
52
+ }
53
+ return undefined;
54
+ }
55
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzb2x2ZS1vcHRpb25zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3V0aWxzL3Jlc29sdmUtb3B0aW9ucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQWlCQSxzRUFZQztBQUtELHNFQW9DQztBQTlERCxNQUFNLGVBQWUsR0FBbUM7SUFDdEQsS0FBSyxFQUFFO1FBQ0wsUUFBUSxFQUFFLElBQUk7S0FDZjtDQUNGLENBQUE7QUFFRDs7R0FFRztBQUNILFNBQWdCLDZCQUE2QixDQUMzQyxPQUE2QztJQUU3QyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDYixPQUFPLGVBQWUsQ0FBQTtJQUN4QixDQUFDO0lBRUQsT0FBTztRQUNMLEtBQUssRUFBRTtZQUNMLFFBQVEsRUFBRSxPQUFPLENBQUMsS0FBSyxFQUFFLFFBQVEsSUFBSSxlQUFlLENBQUMsS0FBSyxDQUFDLFFBQVE7U0FDcEU7S0FDRixDQUFBO0FBQ0gsQ0FBQztBQUVEOztHQUVHO0FBQ0gsU0FBZ0IsNkJBQTZCLENBQzNDLFlBQWtCO0lBRWxCLHVDQUF1QztJQUN2QyxNQUFNLE9BQU8sR0FBRyxZQUFZLEVBQUUsYUFBYSxFQUFFLE9BQU8sSUFBSSxFQUFFLENBQUE7SUFFMUQsS0FBSyxNQUFNLE1BQU0sSUFBSSxPQUFPLEVBQUUsQ0FBQztRQUM3QixJQUFJLE9BQU8sTUFBTSxLQUFLLFFBQVEsRUFBRSxDQUFDO1lBQy9CLElBQUksTUFBTSxLQUFLLGtCQUFrQixFQUFFLENBQUM7Z0JBQ2xDLE9BQU8sRUFBRSxDQUFBO1lBQ1gsQ0FBQztZQUNELFNBQVE7UUFDVixDQUFDO1FBRUQsSUFBSSxNQUFNLEVBQUUsT0FBTyxLQUFLLGtCQUFrQixFQUFFLENBQUM7WUFDM0MsT0FBTyxNQUFNLENBQUMsT0FBdUMsQ0FBQTtRQUN2RCxDQUFDO0lBQ0gsQ0FBQztJQUVELDRDQUE0QztJQUM1QyxNQUFNLGFBQWEsR0FBSSxZQUFvQixFQUFFLE9BQU8sSUFBSSxFQUFFLENBQUE7SUFFMUQsS0FBSyxNQUFNLE1BQU0sSUFBSSxhQUFhLEVBQUUsQ0FBQztRQUNuQyxJQUFJLE9BQU8sTUFBTSxLQUFLLFFBQVEsRUFBRSxDQUFDO1lBQy9CLElBQUksTUFBTSxLQUFLLGtCQUFrQixFQUFFLENBQUM7Z0JBQ2xDLE9BQU8sRUFBRSxDQUFBO1lBQ1gsQ0FBQztZQUNELFNBQVE7UUFDVixDQUFDO1FBRUQsSUFBSSxNQUFNLEVBQUUsT0FBTyxLQUFLLGtCQUFrQixFQUFFLENBQUM7WUFDM0MsT0FBTyxNQUFNLENBQUMsT0FBdUMsQ0FBQTtRQUN2RCxDQUFDO0lBQ0gsQ0FBQztJQUVELE9BQU8sU0FBUyxDQUFBO0FBQ2xCLENBQUMifQ==
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.loadAndRenderTemplate = loadAndRenderTemplate;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ /**
40
+ * Load and render template from file path
41
+ * Supports HTML templates for email notifications
42
+ */
43
+ function loadAndRenderTemplate(templatePath, data) {
44
+ try {
45
+ // Use the exact path provided (can be relative or absolute)
46
+ const fullPath = path.isAbsolute(templatePath)
47
+ ? templatePath
48
+ : path.join(process.cwd(), templatePath);
49
+ if (!fs.existsSync(fullPath)) {
50
+ throw new Error(`Template file not found: ${fullPath}`);
51
+ }
52
+ let templateContent = fs.readFileSync(fullPath, "utf-8");
53
+ // Replace template variables {{variable_name}} with actual values
54
+ Object.keys(data).forEach((key) => {
55
+ const value = data[key];
56
+ const regex = new RegExp(`\\{\\{${key}\\}\\}`, "g");
57
+ if (value !== null && value !== undefined) {
58
+ if (typeof value === "object") {
59
+ templateContent = templateContent.replace(regex, JSON.stringify(value));
60
+ }
61
+ else {
62
+ templateContent = templateContent.replace(regex, String(value));
63
+ }
64
+ }
65
+ else {
66
+ templateContent = templateContent.replace(regex, "");
67
+ }
68
+ });
69
+ // Clean up any remaining placeholders
70
+ templateContent = templateContent.replace(/\{\{[\w]+\}\}/g, "");
71
+ return templateContent;
72
+ }
73
+ catch (error) {
74
+ console.error(`[order-management] Failed to load template from ${templatePath}:`, error);
75
+ return null;
76
+ }
77
+ }
78
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVtcGxhdGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvdXRpbHMvdGVtcGxhdGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFtQkEsc0RBMkNDO0FBOURELHVDQUF3QjtBQUN4QiwyQ0FBNEI7QUFjNUI7OztHQUdHO0FBQ0gsU0FBZ0IscUJBQXFCLENBQ25DLFlBQW9CLEVBQ3BCLElBQXVCO0lBRXZCLElBQUksQ0FBQztRQUNILDREQUE0RDtRQUM1RCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQztZQUM1QyxDQUFDLENBQUMsWUFBWTtZQUNkLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsRUFBRSxZQUFZLENBQUMsQ0FBQTtRQUUxQyxJQUFJLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDO1lBQzdCLE1BQU0sSUFBSSxLQUFLLENBQUMsNEJBQTRCLFFBQVEsRUFBRSxDQUFDLENBQUE7UUFDekQsQ0FBQztRQUVELElBQUksZUFBZSxHQUFHLEVBQUUsQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFFLE9BQU8sQ0FBQyxDQUFBO1FBRXhELGtFQUFrRTtRQUNsRSxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFO1lBQ2hDLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxHQUE4QixDQUFDLENBQUE7WUFDbEQsTUFBTSxLQUFLLEdBQUcsSUFBSSxNQUFNLENBQUMsU0FBUyxHQUFHLFFBQVEsRUFBRSxHQUFHLENBQUMsQ0FBQTtZQUVuRCxJQUFJLEtBQUssS0FBSyxJQUFJLElBQUksS0FBSyxLQUFLLFNBQVMsRUFBRSxDQUFDO2dCQUMxQyxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVEsRUFBRSxDQUFDO29CQUM5QixlQUFlLEdBQUcsZUFBZSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFBO2dCQUN6RSxDQUFDO3FCQUFNLENBQUM7b0JBQ04sZUFBZSxHQUFHLGVBQWUsQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFBO2dCQUNqRSxDQUFDO1lBQ0gsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLGVBQWUsR0FBRyxlQUFlLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQTtZQUN0RCxDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQUE7UUFFRixzQ0FBc0M7UUFDdEMsZUFBZSxHQUFHLGVBQWUsQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLEVBQUUsRUFBRSxDQUFDLENBQUE7UUFFL0QsT0FBTyxlQUFlLENBQUE7SUFDeEIsQ0FBQztJQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7UUFDZixPQUFPLENBQUMsS0FBSyxDQUNYLG1EQUFtRCxZQUFZLEdBQUcsRUFDbEUsS0FBSyxDQUNOLENBQUE7UUFDRCxPQUFPLElBQUksQ0FBQTtJQUNiLENBQUM7QUFDSCxDQUFDIn0=
package/README.md CHANGED
@@ -36,6 +36,105 @@
36
36
 
37
37
  This starter is compatible with versions >= 2.4.0 of `@medusajs/medusa`.
38
38
 
39
+ ## Features
40
+
41
+ - **Order Management**: Cancel and reorder functionality for orders
42
+ - **Order Confirmation Emails**: Automatically sends email notifications when orders are placed (requires template configuration)
43
+
44
+ ## Configuration
45
+
46
+ The plugin can be configured in your `medusa-config.js` file:
47
+
48
+ ```js
49
+ module.exports = defineConfig({
50
+ // ...
51
+ plugins: [
52
+ {
53
+ resolve: "order-management",
54
+ options: {
55
+ email: {
56
+ template: "src/templates/emails/order-confirmation.html", // Path to HTML template file
57
+ },
58
+ },
59
+ },
60
+ ],
61
+ })
62
+ ```
63
+
64
+ ### Configuration Options
65
+
66
+ | Option | Type | Default | Description |
67
+ |--------|------|---------|-------------|
68
+ | `email.template` | `string \| null` | `null` | Path to HTML template file for order confirmation emails (relative to project root or absolute path) |
69
+
70
+ **Note**: Order confirmation emails are only sent if a template path is provided. If no template is configured, emails will not be sent.
71
+
72
+ ## Email Templates
73
+
74
+ The plugin supports custom HTML templates for order confirmation emails. Templates use variable replacement with `{{variable_name}}` syntax.
75
+
76
+ ### Creating Templates
77
+
78
+ Create HTML template files for email notifications. Place them in your project, for example:
79
+
80
+ ```
81
+ your-project/
82
+ src/
83
+ templates/
84
+ emails/
85
+ order-confirmation.html
86
+ ```
87
+
88
+ **Example Email Template** (`src/templates/emails/order-confirmation.html`):
89
+
90
+ ```html
91
+ <!DOCTYPE html>
92
+ <html>
93
+ <head>
94
+ <meta charset="UTF-8">
95
+ <style>
96
+ body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; }
97
+ .container { max-width: 600px; margin: 0 auto; padding: 20px; }
98
+ .header { background-color: #4CAF50; color: white; padding: 20px; text-align: center; }
99
+ .content { padding: 20px; background-color: #ffffff; }
100
+ .order-info { background-color: #f5f5f5; padding: 15px; margin: 15px 0; border-radius: 5px; }
101
+ </style>
102
+ </head>
103
+ <body>
104
+ <div class="container">
105
+ <div class="header">
106
+ <h1>Order Confirmation</h1>
107
+ </div>
108
+ <div class="content">
109
+ <div class="order-info">
110
+ <p><strong>Order ID:</strong> {{order_id}}</p>
111
+ <p><strong>Status:</strong> {{order_status}}</p>
112
+ <p><strong>Total:</strong> {{order_total}}</p>
113
+ <p><strong>Email:</strong> {{order_email}}</p>
114
+ <p><strong>Date:</strong> {{order_date}}</p>
115
+ </div>
116
+ <p>Thank you for your order!</p>
117
+ </div>
118
+ </div>
119
+ </body>
120
+ </html>
121
+ ```
122
+
123
+ ### Template Variables
124
+
125
+ The following variables are available in order confirmation email templates:
126
+
127
+ | Variable | Description | Example |
128
+ |----------|-------------|---------|
129
+ | `{{order_id}}` | Order ID | `order_123` |
130
+ | `{{order_status}}` | Order status | `pending` |
131
+ | `{{order_total}}` | Order total amount | `99.99` |
132
+ | `{{order_email}}` | Customer email address | `customer@example.com` |
133
+ | `{{order_date}}` | Order creation date | `2024-01-15T10:30:00Z` |
134
+ | `{{order_items}}` | Order items array (JSON stringified) | `[{"title":"Product","quantity":1}]` |
135
+ | `{{shipping_address}}` | Shipping address object (JSON stringified) | `{"first_name":"John",...}` |
136
+ | `{{billing_address}}` | Billing address object (JSON stringified) | `{"first_name":"John",...}` |
137
+
39
138
  ## Getting Started
40
139
 
41
140
  Visit the [Quickstart Guide](https://docs.medusajs.com/learn/installation) to set up a server.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "order-management",
3
- "version": "0.0.8",
3
+ "version": "0.0.10",
4
4
  "description": "A starter for Medusa plugins.",
5
5
  "author": "Medusa (https://medusajs.com)",
6
6
  "license": "MIT",