Invoices medusa
Add invoices to Medusa v2
@webbers/invoices-medusa
A Medusa v2 plugin that automatically generates sequential PDF invoices for orders and credit notes for refunds. PDFs are uploaded to your private file storage bucket and served to customers and admins via presigned URLs.
Requirements
- Medusa
- A configured File Module Provider (e.g. S3/R2) with private bucket support
Installation
Configuration
Register the plugin in :
Configuration reference
| Option | Type | Required | Description |
|---|---|---|---|
| No | Fallback locale when is absent or invalid. Defaults to . | ||
| Yes | Company name shown on the invoice. | ||
| Yes | Function returning the company address. Receives the i18n country name map for the resolved locale. | ||
| Yes | Chamber of Commerce number. | ||
| Yes | VAT registration number. | ||
| Yes | Bank account number. | ||
| Yes | Billing contact e-mail. | ||
| No | SVG string or data URL used in the default header. | ||
| No | Rendered logo width in points. | ||
| No | Table header fill color (CSS hex). | ||
| No | Table header text color (CSS hex). | ||
| No | pdfmake content block rendered as page header. Replaces the default logo header. | ||
| No | pdfmake content block rendered as page footer. |
How it works
Invoice lifecycle
- Fulfillment created — the subscriber fires , which:
- Creates a debit invoice record with an auto-incremented
- Links it to the order via the link table
- Generates the PDF and uploads it to the private storage bucket
- Stores the file ID in
- Refund processed — follows the same steps for a credit invoice, referencing the original debit invoice as its parent.
- Download requested — the API route resolves to a presigned download URL via and redirects the client. Invoices without a stored PDF (created before this feature) are generated on-demand as a fallback.
Invoice numbering
is a PostgreSQL auto-increment sequence. Voided invoices (created by workflow compensation on failure) preserve their sequence number to avoid gaps.
Localization
The PDF language is determined by . The value is validated against the list of supported locales; if it is absent or unrecognised, from the plugin config is used.
Supported locales:
| Value | Language |
|---|---|
| Dutch | |
| Dutch (Belgium) — uses Dutch translations | |
| English | |
| German | |
| French | |
| Italian |
Set the locale on an order at creation time:
API routes
Admin
GET /admin/orders/:id/invoice/:invoice_idRequires admin authentication. Redirects to a presigned download URL for the invoice PDF.
Store
GET /store/orders/:id/invoiceRequires customer authentication. Returns the debit invoice PDF for the order. The order must belong to the authenticated customer.
Workflows
The workflows can be called directly from your own subscribers, jobs, or API routes.
Creates a debit invoice, links it to an order, and generates + uploads the PDF.
Creates a credit invoice for a refund.
Generates an invoice PDF on-demand and returns it as a base64 string. Useful for attaching to notification emails.
Backfill script
To generate and upload PDFs for invoices created before file storage was introduced:

