@agilo/medusa-invoices-plugin
v1.0.0
Published
Professional invoice generation plugin for MedusaJS with customizable templates and automatic PDF creation.
Readme
Compatibility
This plugin is compatible with versions >= 2.11.3 of @medusajs/medusa.
Description
A comprehensive invoice generation plugin for MedusaJS that automatically generates PDF invoices for orders with customizable templates.
Features
- 🧾 Automatic invoice generation on selected triggers (e.g. Order completed)
- 📄 PDF generation with customizable templates
- 🎨 Template management with versioning
- 📁 Integration with MedusaJS File Module
- 🔧 Admin UI for configuration and manual generation
- 🔔 Event-based architecture
- 📊 Invoice status tracking
Installation
Prerequisites
- MedusaJS server
- Configured File Module (S3, local, or other provider)
- Node.js 20+
Visit the Quickstart Guide to set up a server. Visit the Plugins documentation to learn more about plugins. Visit the Docs to learn more about medusa system requirements.
Install the plugin
npm install @agilo/medusa-invoices-pluginor with yarn:
yarn add @agilo/medusa-invoices-pluginAdd to medusa-config.ts
import { defineConfig } from "@medusajs/framework";
export default defineConfig({
projectConfig: {
// ... other config
},
plugins: [
{
resolve: "@agilo/medusa-invoices-plugin",
options: {
// Additional options can be configured here
},
},
],
});Configuration
1. Configure File Module
The plugin requires a configured File Module to store generated PDF invoices. If not already configured, add one of the following to your medusa-config.ts:
Example: Local File Storage
// medusa-config.ts
import { defineConfig } from "@medusajs/framework";
export default defineConfig({
// ...
modules: [
{
resolve: "@medusajs/medusa/file",
options: {
providers: [
{
resolve: "@medusajs/medusa/file-local",
id: "local",
options: {
// provider options...
},
},
],
},
},
],
});Example: AWS S3 Storage
// medusa-config.ts
import { defineConfig } from "@medusajs/framework";
export default defineConfig({
// ...
modules: [
{
resolve: "@medusajs/medusa/file",
options: {
providers: [
{
resolve: "@medusajs/medusa/file-s3",
id: "s3",
options: {
file_url: process.env.S3_FILE_URL,
access_key_id: process.env.S3_ACCESS_KEY_ID,
secret_access_key: process.env.S3_SECRET_ACCESS_KEY,
region: process.env.S3_REGION,
bucket: process.env.S3_BUCKET,
endpoint: process.env.S3_ENDPOINT,
// other options...
},
},
],
},
},
],
});Visit the File Module documentation to learn more about file module.
2. Run Database Migrations
After installing the plugin, run migrations to create necessary database tables:
npx medusa db:migrateor with yarn:
yarn medusa db:migrateThis will create tables for:
- Invoice settings
- Invoice records
- Store and invoice settings link
- Order and invoice link
3. Configure Invoice Settings
Access the Admin UI at /app/settings/invoices to:
- Set up default invoice template
- Configure company information
- Select auto-generation triggers
API Documentation
Admin Endpoints
All admin endpoints require authentication with admin privileges.
Get Invoice Settings
GET /admin/invoice-settingsResponse:
{
"settings": {
"id": "invset_01",
"template_id": "clean",
"template_version": "1.0.0",
"header_logo_type": "text",
"header_logo_text": "Agilo",
"header_logo_url": null,
"header_content": {},
"footer_content": {},
"store_name": "Store1",
"store_address": "Some Street 218",
"store_tax_id": "1",
"bank_account_iban": "12345678910",
"bank_account_swift": "25",
"auto_generate_on": [],
"created_at": "2025-12-17T12:30:24.315Z",
"updated_at": "2026-01-27T08:20:43.756Z",
"deleted_at": null
},
"templates": [
{
"id": "clean",
"label": "Clean",
"version": "1.0.0"
},
{
"id": "classic",
"label": "Classic",
"version": "1.0.0"
},
{
"id": "compact",
"label": "Compact",
"version": "1.0.0"
}
],
"availableTriggers": ["order.completed", "order.fulfillment_created", "payment.captured"]
}Update Invoice Settings
POST /admin/invoice-settingsBody:
{
template_id: "clean",
template_version: "1.0.0",
header_logo_type: "text",
header_logo_url: null,
header_logo_text: "Agilo",
header_content: {},
footer_content: {},
store_name: "Store2",
store_address: "Some Street 118",
store_tax_id: "2",
bank_account_iban: "10987654321",
bank_account_swift: "24",
auto_generate_on: []
}Response:
{
"id": "invset_01",
"template_id": "clean",
"template_version": "1.0.0",
"header_logo_type": "text",
"header_logo_text": "Agilo",
"header_logo_url": null,
"header_content": {},
"footer_content": {},
"store_name": "Store2",
"store_address": "Some Street 118",
"store_tax_id": "2",
"bank_account_iban": "10987654321",
"bank_account_swift": "24",
"auto_generate_on": [],
"created_at": "2025-12-17T12:30:24.315Z",
"updated_at": "2026-01-27T08:20:43.756Z",
"deleted_at": null,
"store_id": "store_01"
}Get Invoices by Order ID
GET /admin/invoices/{order_id}Response:
{
"invoices": [
{
"id": "inv_01",
"status": "completed",
"completed_at": "2026-01-26T10:27:31.450Z",
"pdf_url": "http://inv_01.pdf",
"template_id": "compact",
"template_version": "1.0.0",
"error_message": null,
"order_display_id": 1,
"created_by_event": "manual",
"created_at": "2026-01-26T10:27:30.580Z"
},
{
"id": "inv_02",
"status": "completed",
"completed_at": "2026-01-26T09:04:05.957Z",
"pdf_url": "http://inv_02.pdf",
"template_id": "compact",
"template_version": "1.0.0",
"error_message": null,
"order_display_id": 2,
"created_by_event": "manual",
"created_at": "2026-01-26T09:04:05.620Z"
}
],
"count": 2,
"offset": 0,
"limit": 20
}Get Invoice by Order ID
GET /admin/invoices/{order_id}/recentResponse:
{
"status": "completed",
"completed_at": "2026-01-26T13:43:15.758Z",
"pdf_url": "http://inv_01.pdf",
"template_id": "compact",
"template_version": "1.0.0",
"error_message": null,
"order_display_id": 1,
"created_by_event": "manual",
"created_at": "2026-01-26T13:43:15.514Z"
}Generate Invoice
POST /admin/invoices/{order_id}/generateBody:
{
created_by_event: "manual";
template_id: "clean"; // Optional
}Response:
{
"id": "inv_01",
"order_id": "order_01",
"order_display_id": 1,
"status": "completed",
"completed_at": "2026-01-27T09:32:12.233Z",
"pdf_url": "http://inv_01.pdf",
"template_id": "clean",
"template_version": "1.0.0",
"settings_snapshot": {
"store_name": "Store1",
"header_logo": {
"url": null,
"text": "Agilo",
"type": "text"
},
"template_id": "clean",
"store_tax_id": "1",
"store_address": "Some Street 218",
"footer_content": {},
"header_content": {},
"template_version": "1.0.0",
"bank_account_iban": "12345678910",
"bank_account_swift": "25"
},
"error_message": null,
"created_by_event": "manual",
"created_at": "2026-01-27T09:32:11.896Z",
"updated_at": "2026-01-27T09:32:12.234Z",
"deleted_at": null
}Store Endpoint
Customers can access and download their own invoice PDFs.
Get Customer Invoice PDF
GET /store/invoices/{order_id}.pdfResponse:
- returns a PDF file stream
Note: Customers can only access invoices for their own orders. Authentication is required.
Admin UI Guide
Invoice Settings
Accessing Invoice Settings
Navigate to Settings → Invoices in the Medusa Admin dashboard.
Settings Page Features
The settings page allows you to:
Select Active Template
- Choose which template to use for invoice generation
- Preview templates before activating (with dummy or selected order data)
Input Company Information
- Configure store name, address, header, footer...
- This information appears on all generated invoices
- Select Active Auto Generation Triggers
- Choose the trigger on which the invoice is generated
- Possible triggers: Order completed, Fulfillment created, Payment captured
Invoice Widget
Accessing Invoice Widget
Navigate to Orders → Select one order in Medusa Admin dashboard.
Invoice Widget Features
The widget allows you to:
- View latest invoice data
- Manually generate invoice
- View invoice status
- Queued (waiting for invoice generation)
- Generating (invoice is being generated)
- Completed (invoice was successfully generated)
- Failed (invoice generation was unsuccessful)
- View invoice history
- List of all invoices generated for that order
- Possible to filter by particular attributes
Events
The plugin emits events that you can subscribe to for custom workflows.
invoice.generated
Emitted when an invoice is successfully generated.
Payload (event.data):
{
invoice_id: string,
order_id: string,
order_display_id: number,
pdf_url: string,
template_id: "clean" | "classic" | "compact",
template_version: string,
completed_at: Date | string
}invoice.failed
Emitted when invoice generation fails.
Payload (event.data):
{
order_id: string,
error_message: string
}How to Subscribe to Events
Create a subscriber in your Medusa project:
// src/subscribers/invoice.ts
import { SubscriberArgs, type SubscriberConfig } from "@medusajs/framework";
type InvoiceGeneratedPayload = {
invoice_id: string;
order_id: string;
order_display_id: number;
pdf_url: string;
template_id: string;
template_version: string;
completed_at: string;
};
export default async function invoiceHandler({
event,
container,
}: SubscriberArgs<InvoiceGeneratedPayload>) {
const { name, data } = event;
console.log(`invoices: subscriber triggered for event ${name}`);
// Your custom logic here
}
export const config: SubscriberConfig = {
event: ["invoice.generated"],
};Contributing
We welcome contributions and feedback. To get involved, open an issue or submit a pull request on GitHub →
