Customer Upload Experience
Multi-file support, up to N files per item (configurable)
Lets customers upload files to each item in a Magento 2 order, such as artwork, engraving text or prescriptions. Files show in the cart, minicart, checkout and admin order view, with a set limit of files per item.
Key Features:
Additional Services
Built-in from day one. No add-ons, no upsell, no licence keys to renew.
Multi-file support, up to N files per item (configurable)
Attachments appear on quote items as rich additional_options cards
Dedicated admin grid, Sales → Panth Infotech → Order Attachments
Per-product attribute, panth_allow_order_attachment (Yes/No)
MEQP compliant, Adobe Magento Extension Quality Program tested
Panth Order Attachments is a Magento 2 file upload extension that lets customers attach files to specific order items at checkout for print-on-demand, custom artwork, and B2B workflows.
The Panth Order Attachments extension adds a per-item file upload field to Magento 2 and Adobe Commerce checkout, so shoppers can send artwork, engraving instructions, prescriptions, RFQ documents, or personalization assets alongside the order itself, without follow-up emails or support tickets.
It is built for Magento 2 merchants selling print-on-demand apparel, engraved jewelry, personalized gifts, prescription eyewear, business cards, and B2B configured products where every order needs supporting files. A simple product attribute toggles uploads on or off per SKU, so the field only shows where it belongs.
Admins manage every uploaded file from a dedicated grid with thumbnail previews, one-click downloads, order and item linking, multi-file support, and configurable size and MIME-type validation. Customers get a frictionless checkout, and the store gets a clean, searchable backend instead of a flooded inbox.
Best for:
Panth Order Attachments adds per-item file uploads to Magento 2 checkout with a full admin management layer.
Panth Order Attachments lets customers upload files for a specific product before they add it to the cart. The files stay linked to the cart line item, follow it through checkout and, once the order is placed, are attached to the order item. Customers see their files on the order page in their account; store staff download them from the admin order view or from a dedicated attachments grid. Typical uses are artwork for print products, prescriptions, reference images and documents that belong to one line item.
The module adds an upload widget to the product page (and to the cart "edit item" page), stores the files outside the web root under var/panth/order-attachments/, serves them only through access-checked controllers, records each file in its own database table and writes an "Attachments" line into the quote item options so the files are listed with the item in the cart, mini cart, checkout summary and order. Both the Hyva theme (Alpine.js template) and the Luma theme (plain JavaScript template) are supported.
Product page: kishansavaliya.com/magento-2-order-attachments.html
panth_allow_order_attachment: Use Config Setting, Yes or No), plus an "Enable for All Products" switch that decides for every product left on "Use Config Setting".Panth\Core\Security\UploadExtensionPolicy; SVG, HTML, XML and script types are always refused), file content (the detected MIME type must match the extension, images must be readable images, HTML/script/PHP content is refused), file size and product permission. The templates apply the same extension, size and file-count limits before uploading.var/panth/order-attachments/<product_id>/; the original file name is kept in the database and used for downloads.orderattachments/upload/save and gets a database record with status 1 and no cart item yet. The widget shows a counter (for example "2/3"), a progress bar per file, an image thumbnail or an extension badge, and a text field for a note.orderattachments/upload/delete); this sets the record status to 0. The file stays on disk. orderattachments/upload/listing?product_id=<id> returns the current visitor's active uploads for that product that are not yet linked to a cart item or order.Magento\Checkout\Controller\Cart\Add links the records to the new quote item, stores the note on each record and adds an "Attachments" entry to the item's additional options. On Hyva the entry is HTML with thumbnails (opened in a lightbox); on Luma it is a text list of file names.Magento\Checkout\Controller\Cart\UpdateItemOptions links newly added files, unlinks removed ones and rewrites the "Attachments" option. Submitting the edit with no files removes the option.sales_model_service_quote_submit_success) the observer Observer\CopyAttachmentsToOrder writes the order ID and order item ID to each active attachment of the ordered quote items.My Account > My Orders > View Order shows an "Order Attachments" section below the order information, grouped by product, with image thumbnails, file type and size, the note and a download link (orderattachments/download/index?id=<attachment_id>).
order_additional_info) lists file name with type and size, product (linked to the product edit page), uploaded by (customer email, "Customer #panth_order_attachment table with filters, column control, bookmarks and paging. Status shows "Active" (1) or "Deleted" (0). The Actions column offers Download (panth_orderattachments/attachment/download); image previews are loaded through panth_orderattachments/attachment/preview.var/panth/order-attachments/<product_id>/<random-hex>.<ext>, which is not served by the web server. The stored name comes from a cryptographically random generator; the original name is only kept in the database. Files uploaded by earlier versions to pub/media/panth/order-attachments/ are moved to the same relative path under var/ by the data patch MoveLegacyUploadsToPrivateStorage during bin/magento setup:upgrade; the stored paths in panth_order_attachment are relative, so the download links keep working and the old direct media URLs return 404. Copies of those files held in database media storage (media_storage_file_storage) are also written to var/ and removed from the database. A file that cannot be moved is logged and left in place; the controllers still find it there (they look in var/ first, then pub/media/). The module itself does not build direct media URLs.var/panth/order-attachments/ and are never copied into database media storage, whatever "Media Storage" is set to. On a setup with several web nodes, var/panth/order-attachments/ must be on storage shared by all nodes.orderattachments/download/index) is allowed for the owner as described above; order attachments require the logged-in order owner. The file is always sent as application/octet-stream with Content-Disposition: attachment and the original file name.orderattachments/thumbnail/view) serves only JPEG, PNG, GIF, WebP and BMP files to the owner, with X-Content-Type-Options: nosniff and a sandboxing Content-Security-Policy. Everything else gets a 404.orderattachments/upload/delete) is refused for attachments that already have an order ID and for attachments not owned by the current visitor.Panth_OrderAttachments::attachment_download; admin preview requires Panth_OrderAttachments::attachment_view.| Template | Used for |
|---|---|
view/frontend/templates/product/view/upload.phtml |
Upload widget on Hyva (Alpine.js); applied through default_hyva.xml |
view/frontend/templates/luma/product/view/upload.phtml |
Upload widget on Luma (plain JavaScript); block product.order.attachments.upload, alias form_top inside product.info |
view/frontend/templates/lightbox.phtml |
Lightbox script added before the closing body tag on every storefront page while the module is enabled |
view/frontend/templates/order/view/attachments-frontend.phtml |
"Order Attachments" section on the customer order view |
view/adminhtml/templates/order/view/attachments.phtml |
"Order Attachments" section on the admin order view |
Colour tokens for the widget are defined in etc/theme-config.json and registered with Panth\Core\ViewModel\ThemeConfig through etc/frontend/di.xml.
USER_GUIDE.md is written for store administrators and covers installation, verifying the module is active, every configuration setting, enabling attachments on products, how customers use the widget in the product page, cart, cart edit and checkout, the admin order view and attachments grid, the customer order view, and troubleshooting.
See CHANGELOG.md.
| Platform | Versions |
|---|---|
| Magento Open Source | 2.4.4, 2.4.5, 2.4.6, 2.4.7, 2.4.8 (as published on the product page) |
| Adobe Commerce | 2.4.4, 2.4.5, 2.4.6, 2.4.7, 2.4.8 (as published on the product page) |
| PHP | >=8.1 (from composer.json) |
| Themes | Hyva (Alpine.js template) and Luma (plain JavaScript template) |
Composer constraints on Magento packages: magento/framework ^103.0, magento/module-catalog ^104.0, magento/module-sales ^103.0, magento/module-quote ^101.0, magento/module-checkout ^100.4, magento/module-eav ^102.0, magento/module-customer ^103.0, magento/module-store ^101.1, magento/module-media-storage ^100.4, magento/module-backend ^102.0, magento/module-ui ^101.2.
mage2kishan/module-core ^1.0.17 (module Panth_Core). It provides the theme detection helper, the upload extension policy and the "Panth Infotech" admin menu that this module hooks into.composer require mage2kishan/module-order-attachments
bin/magento module:enable Panth_Core Panth_OrderAttachments
bin/magento setup:upgrade
bin/magento setup:di:compile
bin/magento cache:flush
setup:di:compile is only needed when the store runs in production mode. The module ships no files under view/*/web, so no static content deployment is required for it.
Check that the module is enabled:
bin/magento module:status Panth_OrderAttachments
setup:upgrade creates the panth_order_attachment table and the "Allow Order Attachments" product attribute (attribute group "Order Attachments", global scope, default "Use Config Setting").
Admin path: Stores > Configuration > Panth Extensions > Order Attachments. The same page is reachable from the admin menu entry Order Attachments > Configuration. All settings can be set at default, website and store view scope.
Section: "Order Attachments" (panth_orderattachments).
| Setting | Default | What it does |
|---|---|---|
| Enable Order Attachments | Yes | Master switch. When No, the upload widget, the lightbox script and the upload endpoint are disabled. |
| Enable for All Products | No | Shown only when the module is enabled. Applies to products whose "Allow Order Attachments" attribute is "Use Config Setting": Yes shows the widget on them, No hides it. Products set to Yes always show the widget and products set to No never do. |
Config paths: panth_orderattachments/general/enabled, panth_orderattachments/general/enable_all_products.
| Setting | Default | What it does |
|---|---|---|
| Allowed File Extensions | pdf,jpg,jpeg,png,gif,doc,docx,zip | Comma-separated list of extensions accepted by the uploader. Required. Extensions blocked by Panth\Core\Security\UploadExtensionPolicy (executable and script types) are rejected even if listed here. |
| Maximum File Size (MB) | 10 | Maximum size per file in megabytes. Required, whole number greater than zero. Checked in the browser and again on the server; the PHP upload_max_filesize and post_max_size limits still apply. |
| Maximum Files Per Item | 3 | Maximum number of files per cart line item. Required, whole number greater than zero. Enforced by the upload widget and again on the server when files are linked to a cart item (add to cart and cart item update); extra files are left unlinked and the customer sees a warning. |
Config paths: panth_orderattachments/upload/allowed_extensions, panth_orderattachments/upload/max_file_size, panth_orderattachments/upload/max_files_per_item.
| Setting | Default | What it does |
|---|---|---|
| Upload Button Label | Attach Files | Text shown on the upload button and as the widget heading. When empty, "Attach Files" is used. |
Config path: panth_orderattachments/display/upload_label. The "Attachments" item option is always written to the cart item and is shown wherever Magento prints item options (cart, mini cart, checkout summary, order).
Catalog > Products > edit product > attribute group "Order Attachments" > "Allow Order Attachments" (Use Config Setting, Yes or No; default Use Config Setting). The attribute has global scope.
bin/magento module:disable Panth_OrderAttachments
composer remove mage2kishan/module-order-attachments
bin/magento setup:upgrade
bin/magento setup:di:compile
bin/magento cache:flush
The following remain after removal and must be cleaned up by hand if no longer wanted: the panth_order_attachment table, the configuration rows under panth_orderattachments/ in core_config_data, the product attribute panth_allow_order_attachment, the uploaded files under var/panth/order-attachments/ and pub/media/panth/order-attachments/, and the "Attachments" entries stored in the additional options of existing quote and order items.
Commercial software license. See LICENSE.txt in this repository.
Panth_OrderAttachments; Composer package: mage2kishan/module-order-attachments; namespace: Panth\OrderAttachments.Panth_Core, Magento_Catalog, Magento_Sales, Magento_Quote, Magento_Checkout.orderattachments (controllers Upload/Save, Upload/Delete, Upload/Listing, Download/Index, Thumbnail/View).panth_orderattachments (controllers Adminhtml/Attachment/Index, Adminhtml/Attachment/Download, Adminhtml/Attachment/Preview).Model\AttachmentAccess (ownership checks), Model\FileLocator (resolves a stored path in var/ or, for older files, pub/media/), Model\Upload\FileValidator (extension, size and content checks), Model\LegacyUploadMigrator (moves files uploaded by earlier versions out of pub/media/; used by the data patch Setup\Patch\Data\MoveLegacyUploadsToPrivateStorage).etc/frontend/di.xml): Plugin\Cart\LinkAttachmentsAfterAddToCart (after Magento\Checkout\Controller\Cart\Add::execute) and Plugin\Cart\UpdateAttachmentsOnCartUpdate (after Magento\Checkout\Controller\Cart\UpdateItemOptions::execute).etc/events.xml, global scope): Observer\CopyAttachmentsToOrder on sales_model_service_quote_submit_success.Model\OrderAttachment (event prefix panth_order_attachment), resource model Model\ResourceModel\OrderAttachment, collection Model\ResourceModel\OrderAttachment\Collection, grid collection Model\ResourceModel\OrderAttachment\Grid\Collection (registered as panth_orderattachments_listing_data_source in etc/di.xml).Block\Product\View\Upload (widget; shouldShow(), getUploadConfig(), getExistingAttachments()), Block\Order\View\Attachments (customer order view), Block\Adminhtml\Order\View\Attachments (admin order view).Helper\Config wraps all configuration paths.panth_orderattachments_listing with column classes Ui\Component\Listing\Column\Thumbnail, FileSize, ProductName and Actions.Setup\Patch\Data\AddAllowOrderAttachmentAttribute creates the product attribute panth_allow_order_attachment; Setup\Patch\Data\UseConfigForAllowOrderAttachment turns it into a select with the source model Model\Product\Attribute\Source\AllowOrderAttachment (empty value = Use Config Setting, 1 = Yes, 0 = No) and resets stored No values to Use Config Setting.Panth_OrderAttachments::config (configuration section), Panth_OrderAttachments::attachment_view (grid and menu), Panth_OrderAttachments::attachment_download (admin download).etc/db_schema.xml): panth_order_attachment with columns attachment_id, quote_item_id, order_item_id, order_id, product_id, customer_id, customer_email, original_filename, stored_filename, file_path, file_size, mime_type, file_extension, customer_note, status, created_at, updated_at; indexes on quote_item_id, order_item_id, order_id, product_id and status.order_attachment_ids[] and order_attachment_note on the add-to-cart and update-item forms; product_id, file, customer_note and the honeypot oa_website_url on the upload request.| Module Category | Cart & Checkout |
|---|---|
| Best For | All Sizes |
Native file custom options are tied to the cart quote item and don't persist cleanly as a first-class order record. Panth Order Attachments creates dedicated panth_quote_attachment and panth_order_attachment tables, linked to the sales order item, ensuring files remain accessible for the full order lifetime, including reorders, invoices, and RMAs.
Yes. Set Max Files Per Item in configuration (default 5). Each enabled product in the cart accepts up to that many files.
Yes. The frontend widget has both Luma (PHTML + vanilla JS) and Hyva (Alpine.js + Tailwind) implementations, auto-selected via Panth\Core\Helper\Theme.
Any extension you configure. Defaults: jpg, jpeg, png, gif, pdf, doc, docx, zip. You can add ai, psd, eps, svg, tif, xlsx, etc.
In var/order_attachments/ with SHA-256 hashed filenames. The directory is not publicly browsable; files are served only through authenticated controllers.
Yes. Both guest and registered customer checkouts are supported.
Yes. Admins can soft-delete or download any attachment from the grid and order view tab.
Yes. Files are stored in the writable var/ directory which is persisted across deploys on ACC.
Yes. Configuration respects default → website → store view scope. Attachments are stored per order regardless of store view.
REST endpoints for listing and downloading attachment metadata are included. GraphQL support is on the roadmap.
Talk to Kishan directly: written quote, scope and timeline within 24 hours. No sales call.
Order File Attachments for Magento 2