storetown-media / module-product-attachments
Adds file attachments (PDF, Office, images, videos, YouTube) to products with frontend download and inline preview (PDF, images, txt/csv, Word, Excel, PowerPoint), mass assign, CSV import, auto-assign rules and category grouping for Adobe Commerce / Magento Open Source.
STM Product Attachments for Magento 2 / Adobe Commerce
Attach files (PDF, DOC, images, archives, video, YouTube) to products and display them as a download list with inline preview on the product detail page. Mass-assign from the catalog grid, bulk-import via CSV, or let a rule engine attach files automatically based on product conditions.
Features
- Product Attachments tab on the product edit page with file upload, YouTube URL, title, category and sort order
- Central admin grid under
Catalog > Product Attachments > Manage Attachmentswith column filters, full-text search, mass delete and mass category assign - Mass Assign from the catalog product grid mass-action: upload one file once and attach it to many products at once
- CSV Import with line-by-line validation
- Auto-Assign Rules with condition engine (category, attribute set, any product attribute), AND / OR combinations, optional
Apply on Save, optional nightly cron, automatic FPC flush - Frontend
Attachmentstab with thumbnails, colour-coded file-type badges, file size, download counter - Inline preview modal for PDFs (iframe), images, YouTube videos and direct video files — no page reload, no external viewer
- Attachment categories with sort order and optional grouping on the product page
- Custom file-type badges — upload icon, set label and badge colour per file extension
- Customer-group access restrictions with separate guest-download toggle
- Store-view-aware configuration for every setting
- English + German translations included; ready for additional languages via standard Magento i18n CSV files
- Clean code: PSR-4, strict types, declarative schema, service contracts, no core rewrites, Adobe EQP-compliant
Requirements
- Magento Open Source 2.4.x or Adobe Commerce 2.4.x
- PHP 8.1, 8.2, 8.3 or 8.4
Installation
Via Composer (recommended)
composer require storetown-media/module-product-attachments
bin/magento module:enable STM_ProductAttachments
bin/magento setup:upgrade
bin/magento setup:di:compile
bin/magento cache:flush
Manual installation
- Extract the archive so the module sources land under
app/code/STM/ProductAttachments/. - Run:
bin/magento module:enable STM_ProductAttachments
bin/magento setup:upgrade
bin/magento setup:di:compile
bin/magento cache:flush
If Magento is in production mode, also run bin/magento setup:static-content:deploy for every active locale.
Usage
Adding attachments to a product
- Open a product in Catalog > Products.
- Scroll down to the Product Attachments tab.
- Click Add Attachment, upload a file (or paste a YouTube URL), enter a title, optionally assign a category and set a sort order.
- Save the product.
Mass assign from the product grid
- Go to Catalog > Products and select multiple products.
- From the Actions dropdown choose Assign Attachment.
- Upload the file, enter a title and click Assign.
CSV import
- Open Catalog > Product Attachments > Import Attachments.
- Upload your attachment files to
pub/media/import/attachments/. - Prepare a CSV with the columns
sku, title, file_path(required) andcategory, sort_order(optional). - Pick the CSV and click Import.
Auto-assign rules
- Open Catalog > Product Attachments > Auto-Assign Rules.
- Click Add Rule, name the rule, upload the file and define one or more conditions on category, attribute set or any product attribute.
- Set
Apply on Saveto attach immediately when the rule is saved, or trigger via the Apply action in the rule grid, or wait for the optional nightly cron.
Frontend display
Attachments appear as a tab on the product detail page. Image files show a thumbnail; other file types display a colour-coded badge (red for PDF, blue for Word, green for Excel, …). Each row offers Preview (inline modal) and Download actions.
Configuration
All settings live under Stores > Configuration > STM > Product Attachments and are scope-aware down to the store view. Configuration groups: Manage & Import, General, File, Display, Attachment Categories, File Extension Icons, Auto-Assign Rules, Access Restrictions.
File storage
Uploaded files are stored under pub/media/stm/attachments/. Custom file-extension icons under pub/media/stm/extension_icons/. CSV import expects the source files under pub/media/import/attachments/.
Uninstall
bin/magento module:disable STM_ProductAttachments
bin/magento setup:upgrade
bin/magento cache:flush
To fully uninstall via Composer, run bin/magento module:uninstall STM_ProductAttachments followed by the standard upgrade / compile / flush sequence.
The module creates four own tables (stm_product_attachments, stm_attachment_categories, stm_attachment_file_extensions, stm_attachment_rules) and does not modify any Magento core tables. Uploaded files remain under pub/media/stm/attachments/ after uninstall and can be removed manually.
License
Commercial — Storetown Media Commercial License. See LICENSE.txt for full terms.
Support
Issues, questions and feature requests are handled by Storetown Media. Use the support link on the Adobe Commerce Marketplace listing or write to [email protected]. Expected response time is within two business days.
Changelog
All notable changes to STM Product Attachments will be documented in this file.
[2.1.0] - 2026-04-25
Added
- Inline preview now supports plain-text files (
.txt), CSV (.csv), Word (.doc/.docx), Excel (.xls/.xlsx) and PowerPoint (.pptx) in addition to PDF, images and video. Office documents are rendered server-side to clean HTML by PhpSpreadsheet, PhpWord and PhpPresentation — no third-party viewer (e.g. Microsoft Office Online Viewer) and no extra Content-Security-Policy host whitelist required. CSV files are parsed with auto-detected delimiter and rendered as a styled table; PPTX slides are rendered as 16:9 slide-cards with heading detection and bullet indent levels. - Legacy binary
.pptfiles surface a friendly "save as .pptx and re-upload" message inside the preview iframe rather than failing silently.
Changed
- Preview controller now derives the response
Content-Typefrom the actual file extension (whitelisted map) rather than the storedfile_typecolumn. This makes the preview robust against MIME drift if a file is replaced on disk and the stored MIME no longer matches.
Internal
- Preview overlay re-uses a single
iframeslot for all HTML/PDF-served types (pdf,text,csv,office) via a smalltypeToSlotmapping, instead of one slot per type. - Three new Composer dependencies:
phpoffice/phpspreadsheet,phpoffice/phpword,phpoffice/phppresentation(each MIT-licensed, all maintained by the PhpOffice organisation). - Database schema: column
file_typeextended fromVARCHAR(50)toVARCHAR(100)onstm_product_attachmentsandstm_attachment_rules. The 50-char limit silently truncated Office-XML MIME types (application/vnd.openxmlformats-officedocument.*is 74-78 chars), causing INSERT failures in MySQL strict mode and stored-MIME drift in non-strict mode. Affected columns are now wide enough to hold the full MIME for.docx,.xlsxand.pptx.
[2.0.1] - 2026-04-25
Fixed
- Inline preview now works reliably after a file is replaced on the product edit page. The attachment's
file_typeis now derived server-side from the actual file on disk viafinfowith an extension-based fallback, instead of trusting the client-sent MIME header. The previous behaviour could leave a stale MIME on the database row when the dynamic-rows file uploader carried over the previous file'stype, causing the preview controller to return 404 for any attachment whose stored MIME did not match the file extension. AffectedController/Adminhtml/Manage/Save.php,Controller/Adminhtml/Attachment/MassAssignPost.phpand the CSV importer.
Internal
- New
FileProcessor::detectMimeType(string $relativePath): ?stringconsolidates MIME detection in one place. The duplicate extension map inModel/Import/AttachmentImporter::guessMimeType()was removed in favour of the shared helper.
[2.0.0] - 2026-04-24
First public release on the Adobe Commerce Marketplace. Consolidation of the previously internally distributed Storetown_ProductAttachments 1.x line, renamed to STM_ProductAttachments, audited for Adobe EQP compliance and re-licensed for Marketplace distribution.
Breaking Changes
- Module renamed from
Storetown_ProductAttachmentstoSTM_ProductAttachments. The PHP namespace changed fromStoretown\ProductAttachmentstoSTM\ProductAttachmentsand the install path fromapp/code/Storetown/ProductAttachments/toapp/code/STM/ProductAttachments/. Composer package name changed tostoretown-media/module-product-attachments. The previous internal 1.x line therefore cannot be upgraded in-place; fresh install only. - Database tables renamed:
storetown_product_attachments→stm_product_attachments,storetown_attachment_categories→stm_attachment_categories,storetown_attachment_file_extensions→stm_attachment_file_extensions,storetown_attachment_rules→stm_attachment_rules. Declarative schema cannot rename tables in place; existing 1.x installs must run a custom migration patch or re-import data. - File storage path moved from
pub/media/storetown/attachments/topub/media/stm/attachments/. Custom file-extension icons moved frompub/media/storetown/extension_icons/topub/media/stm/extension_icons/. - System configuration section id changed from
storetown_attachmentstostm_attachments. All config-paths understoretown_attachments/*are now understm_attachments/*. - Admin configuration tab moved from a separate
Storetowntab to the sharedSTMtab so all Storetown Media modules group under one entry inStores > Configuration. - License changed from
OSL-3.0toproprietary(Storetown Media Commercial License) for Marketplace distribution.
Added
Setup/Patch/Data/InstallDefaultFileExtensions.phpseeds the newstm_attachment_file_extensionstable with 15 default file types (PDF, Word, Excel, PowerPoint, Images, Archives, Text) on fresh installation.- Marketplace-ready PHP 8.4 compatibility — explicit nullable type hints on all default-null parameters.
Fixed
- Frontend
Attachmentstab on the product detail page now renders correctly on Luma-based themes. The previous Alpine.js modal directives (x-data,x-show,@click) only worked on Hyvä Theme, leaving Luma users with an unconditionally visible empty preview overlay. Replaced with a dependency-free vanilla-JS implementation that works on Luma, Hyvä and any third-party theme.
Internal
- Refactor Storetown → STM: 950+ string substitutions across 190 files, 18 XML files renamed.
- Removed 14 verwaiste
jedev_*legacy layout / UI files (rebrand cruft from earlier code-base lineage). - Removed dead
attachments.cssexternal file (was not loaded by any layout XML; CSS is inlined inattachments.phtmlfor theme compatibility). - Adobe EQP pre-check passing: PHPCS Magento2 (0 errors / 0 warnings), PHPCompatibility 8.1+ (0 errors), PHPStan (0 real findings).
- Manual security review: 31 / 31 admin controllers ship
ADMIN_RESOURCEACL constants and implementHttpGetActionInterfaceorHttpPostActionInterface(CSRF). 100 % of phtml outputs use the$escaperAPI. NoObjectManager::getInstance(),eval,exec, raw SQL orvar_dumpcalls remain.
[1.2.4] - 2026-03-19
Fixed
- YouTube-Attachments werden beim Produkt-Speichern nicht mehr geloescht
- Product Form Modifier: video_url Feld hinzugefuegt, damit YouTube-Attachments im Admin sichtbar und editierbar sind
- File-Uploader Validierung (required-entry) entfernt, da Attachments auch nur eine YouTube-URL haben koennen
[1.2.3] - 2026-03-19
Fixed
- Kategorie-Reihenfolge im Frontend folgt jetzt korrekt der Category Sort Order aus dem Admin
- Frontend-Tabelle: Spaltenbreiten optimiert fuer den Product-Tab-Container (kein Abschneiden mehr)
- Alte externe CSS-Datei (attachments.css) entfernt, die Konflikte mit den Inline-Styles verursachte
Improved
- Kompakteres Tabellen-Design: kleinere Buttons, Thumbnails und Padding fuer bessere Darstellung
- YouTube-Videos zeigen jetzt ein Play-Icon statt Auge-Icon im Ansehen-Button
- CSS komplett neu geschrieben: theme-unabhaengig, funktioniert mit Hyva, Luma und Custom Themes
- Alle CSS-Klassen umbenannt (sta-badge, sta-btn) um Konflikte mit Magento-Core-Klassen zu vermeiden
- Mobile Ansicht: Flexbox-basiertes Card-Layout statt float-basiertem Hack
[1.2.2] - 2026-03-19
Added
- Extension Info Block im Backend mit Firmenlogo, Kontaktdaten und Support-Informationen auf allen Modulseiten
- Storetown Media Branding in der System-Konfiguration mit vollstaendiger Extensionsbeschreibung und Feature-Uebersicht
- Vorbereitung fuer Composer-Distribution ueber packages.storetown-media.de
Improved
- Finale Code-Qualitaet und Stabilisierung fuer den oeffentlichen Release
- Alle Admin-Seiten (Grids, Formulare, Import, Mass Assign) zeigen nun einheitlich den Info-Block
[1.2.1] - 2026-03-14
Fixed
- Korrektur der Grid-Collection Sortierung bei leeren Filtern im Attachment Grid
- Fehlende Uebersetzungen in der deutschen Lokalisierung (i18n/de_DE.csv) ergaenzt
- CSS-Darstellung der File-Type Badges im Hyva Theme korrigiert
Improved
- Performance-Optimierung beim Laden der Attachment-Liste auf Produktseiten mit vielen Anhaengen
- Bessere Fehlerbehandlung beim Datei-Upload wenn die maximale Dateigroesse ueberschritten wird
[1.2.0] - 2026-03-10
Added
- Auto-Assign Rules -- automatische Zuweisung von Attachments zu Produkten basierend auf flexiblen Bedingungen
- Condition Engine mit Unterstuetzung fuer Produkt-Kategorie, Attribut-Set und beliebige Produktattribute
- AND/OR Verknuepfung mehrerer Bedingungen fuer komplexe Regellogik (z.B. "Kategorie = Elektronik UND Hersteller = Samsung")
- Apply on Save Toggle -- Regeln koennen optional direkt beim Speichern auf alle passenden Produkte angewendet werden
- Naechtliche Cron-Ausfuehrung aller aktiven Regeln (konfigurierbar in System Config, Standard: 02:00 Uhr, default deaktiviert)
- Automatischer Full Page Cache Flush nach Regelanwendung um sofortige Frontend-Aktualisierung sicherzustellen
- Dediziertes Admin Grid fuer Auto-Assign Rules mit Status-Filter, Suche und Mass Delete Aktion
- Rule-Formular mit Datei-Upload, Video-URL, Kategorie-Zuweisung und Sortierung
Improved
- Grid-Architektur fuer alle Listing-Grids grundlegend ueberarbeitet und stabilisiert
- Einheitliche DataProvider-Struktur fuer Attachment, Category, Extension und Rule Grids
[1.1.2] - 2026-02-28
Fixed
- YouTube-Embed URL Generierung bei URLs mit zusaetzlichen Query-Parametern korrigiert
- Modal-Overlay schloss sich nicht korrekt bei Klick ausserhalb des Vorschau-Fensters
- Vorschau-Button wurde bei deaktivierter Preview-Option trotzdem im Frontend angezeigt
Improved
- Alpine.js Modal Transition fuer fluessigerere Animation beim Oeffnen und Schliessen
- Thumbnail-Qualitaet fuer YouTube-Videos auf maxresdefault erhoeht
[1.1.1] - 2026-02-20
Fixed
- CSV-Import brach bei SKUs mit Sonderzeichen (Umlaute, Bindestriche) ab
- Mass Assign Formular zeigte bei grossen Produktmengen (>500) einen Timeout-Fehler
Improved
- Import-Validierung zeigt nun Zeilennummern bei fehlerhaften CSV-Eintraegen an
- Batch-Verarbeitung beim Mass Assign fuer bessere Performance bei grossen Datenmengen
[1.1.0] - 2026-02-10
Added
- Inline Document Preview fuer PDF-Dateien (eingebetteter iframe), Bilder (img-Tag) und YouTube-Videos (Embed)
- Alpine.js Modal fuer interaktive Vorschau direkt auf der Produktseite ohne Seitenneuladen
- Automatische YouTube-Erkennung bei Video-URLs mit Thumbnail-Generierung und korrekter Embed-URL
- Video-URL Feld im Attachment-Formular fuer YouTube-Links und direkte Video-Dateien
- Konfigurierbare Vorschau-Funktion -- aktivierbar/deaktivierbar pro Store View in der System Configuration
- CSV-Import fuer Massenimport von Attachments -- unterstuetzt SKU-basierte Produktzuordnung, Kategorie, Titel und Sortierung
- Dedizierte Import-Seite im Admin unter Catalog > Product Attachments > Import Attachments
- Mass Assign Funktion -- mehrere Attachments gleichzeitig an ausgewaehlte Produkte zuweisen
- Erweiterte Mass Actions im Attachment Grid: Mass Delete und Mass Category Assign
Improved
- Formular-Validierung beim CSV-Import mit detailliertem Fehler-Reporting (Zeile, Feld, Fehlergrund)
- Upload-Fortschrittsanzeige beim Datei-Upload im Attachment-Formular
[1.0.2] - 2026-01-30
Fixed
- Customer Group Restriction wurde bei gecachten Seiten nicht korrekt ausgewertet
- Guest Access Einstellung wurde beim Speichern der Konfiguration nicht persistent gespeichert
Improved
- Cache-Tag Integration fuer korrekte Invalidierung bei Aenderungen an den Zugriffsrechten
[1.0.1] - 2026-01-20
Fixed
- File Extension Icons wurden nach dem Loeschen eines Icons nicht korrekt zurueckgesetzt
- Badge-Farben mit ungueltigem Hex-Wert fuehrten zu einem Frontend-Rendering-Fehler
- Sortierung nach Sort Order im Frontend funktionierte nicht bei Attachments ohne expliziten Sort-Wert
Improved
- Fallback auf Standard-Icons wenn kein benutzerdefiniertes Icon hinterlegt ist
- Validierung der Hex-Farbwerte im File Extension Formular
[1.0.0] - 2026-01-13
Added
- File Extension Management mit eigenem Admin Grid -- individuelle Icons, Labels und Badge-Farben pro Dateityp definierbar
- Icon-Upload Funktion fuer benutzerdefinierte Dateityp-Symbole (PNG, SVG unterstuetzt)
- Konfigurierbare Custom File Extensions in der System Configuration mit Dynamic Rows
- Customer Group Access Restrictions -- Attachments gezielt nur fuer bestimmte Kundengruppen sichtbar machen
- Guest Download Steuerung -- Downloads fuer nicht eingeloggte Besucher separat erlauben oder verbieten
- Store View spezifische Konfiguration fuer alle Zugriffsrechte
Improved
- Frontend-Darstellung mit farbigen File-Type Badges die automatisch anhand der Dateiendung generiert werden
- Responsive Badge-Darstellung fuer mobile Endgeraete optimiert
[0.9.0] - 2025-12-16
Added
- Attachment-Kategorien zur Organisation von Anhaengen (z.B. Handbuecher, Datenblaetter, Zertifikate, Sicherheitsinformationen)
- Kategorie-Management im Admin mit eigenem Grid, Formular und Mass Delete Aktion
- Gruppierung nach Kategorien auf der Produktseite -- konfigurierbar in System Config (Group by Category)
- Sortierung innerhalb von Kategorien ueber Sort Order Feld
- Download Counter mit automatischer Zaehlung und optionaler Anzeige auf der Produktseite
- Konfigurierbare Sortierung der Attachments (nach Name, Erstellungsdatum, Dateigroesse oder manueller Sort Order)
- Option zum Oeffnen von Downloads in neuem Browser-Fenster/Tab
- Anzeige von Dateigroesse (human-readable: KB, MB) und Dateityp neben jedem Attachment
- Alle Display-Optionen einzeln aktivierbar/deaktivierbar in der System Configuration
Improved
- System Configuration um dedizierte Bereiche fuer Kategorie-Verwaltung und Display-Optionen erweitert
- Frontend-Template mit verbesserter Barrierefreiheit (ARIA Labels fuer Download-Links)
[0.8.0] - 2025-11-11
Added
- Attachment Tab in der Produkt-Bearbeitung im Admin -- Attachments koennen direkt am Produkt verwaltet werden
- Datei-Upload mit serverseitiger Validierung (erlaubte Dateitypen konfigurierbar, maximale Dateigroesse einstellbar)
- Admin Grid fuer zentrale Attachment-Verwaltung mit Spaltenfiltern, Volltextsuche und Paginierung
- ACL-Integration fuer granulare Berechtigungen (Manage Attachments, Import, Rules, Configuration)
- Admin-Menue unter Catalog > Product Attachments mit Unterpunkten fuer Manage, Rules und Import
- Quick Action Buttons auf der Konfigurationsseite fuer schnellen Zugriff auf Manage und Import
Improved
- Formular-UX mit automatischer Dateittyp-Erkennung und Groessenberechnung beim Upload
[0.7.0] - 2025-10-14
Added
- Initiale Modulstruktur fuer Magento 2.4.x mit vollstaendigem Repository Pattern
- Datenbank-Schema (Declarative Schema) fuer Attachments, Kategorien, File Extensions und Auto-Assign Rules
- API Interfaces (AttachmentRepositoryInterface, CategoryRepositoryInterface, FileExtensionRepositoryInterface)
- Data Interfaces fuer typsichere Datenmodelle
- Frontend-Block fuer Attachment-Anzeige als eigener Tab auf der Produktseite
- Kompatibilitaet mit Hyva Theme (Alpine.js), Luma Theme und gaengigen Drittanbieter-Themes wie Porto
- Grundlegende System Configuration unter eigenem Storetown Tab mit Sektionen fuer General, File, Display Settings
- CSP Whitelist Konfiguration fuer YouTube Embeds und externe Ressourcen
- Deutsche und englische Uebersetzungsdateien (i18n)
Requires 12
| Package | Constraint |
|---|---|
| magento/framework | ^103.0 |
| magento/module-backend | ^102.0 |
| magento/module-catalog | ^104.0 |
| magento/module-config | ^101.2 |
| magento/module-customer | ^103.0 |
| magento/module-media-storage | ^100.4 |
| magento/module-store | ^101.1 |
| magento/module-ui | ^101.2 |
| php | ~8.1.0||~8.2.0||~8.3.0||~8.4.0 |
| phpoffice/phppresentation | ^0.9 || ^1.0 |
| phpoffice/phpspreadsheet | ^2.0 || ^3.0 || ^4.0 || ^5.0 |
| phpoffice/phpword | ^1.2 |
Requires-dev 1
| Package | Constraint |
|---|---|
| phpunit/phpunit | ^9.5 || ^10.0 |
Compatibility
Each Magento release line is installed on its supported PHP versions, then the module is built (DI compilation + static-content deploy) and its unit and integration suites are run. The matrix shows the lines and PHP versions the module is confirmed to install and run on. Code-quality results further down (phpstan, phpcs, …) are reported separately and never affect compatibility.
Code Quality
Advisory checks against the module's source. Static analysis runs once across the whole module; PHPStan re-runs per Magento + PHP version because resolvable symbols differ between releases. These NEVER affect the Compatibility badge. A phpcs finding can't make a module incompatible.
Static analysis
Coding standards (phpcs), mess detection (phpmd), copy-pasted code (cpd), PHP cross-version compatibility, composer.json validity. Each runs once for the whole module.
PHPStan
Type-checks the module's PHP against a real Magento install at the configured gate level. Re-runs per Magento and PHP version because resolvable symbols differ between releases.
Tests
Unit and integration suites, run for each applicable Magento and PHP version. A test failure speaks to the module's behaviour, not its compatibility with a Magento line, so it is reported here separately and never reddens the compatibility matrix.
Unit tests
| Magento | PHP 8.2 | PHP 8.3 | PHP 8.4 | PHP 8.5 |
|---|---|---|---|---|
| 2.4.7 | N/A | N/A | ||
| 2.4.8 | N/A | N/A | ||
| 2.4.9 | N/A | N/A |
Integration tests
| Magento | PHP 8.2 | PHP 8.3 | PHP 8.4 | PHP 8.5 |
|---|---|---|---|---|
| 2.4.7 | N/A | N/A | ||
| 2.4.8 | N/A | N/A | ||
| 2.4.9 | N/A | N/A |
Security
Security checks run directly against the module: an audit of its declared dependencies for known vulnerabilities (composer audit) and a scan of its source for malware and web-shell signatures. Each runs once. A malware detection fails the version outright.
More from Storetown Media
View vendorAutomatic EU VAT rate synchronization for Magento 2 — imports and updates all European tax rates including automatic Tax Rule creation. Free open-source under MIT.
Magento 2 surcharge module with category- and product-level rules, named reusable rules with per-product binding and bulk-assign from the catalog grid, tier and customer-group pricing, conditional caps (min/max/free-threshold) and country-based shipping restriction.
One Page Checkout for Magento 2 — All checkout steps on a single page with AJAX validation, real-time shipping calculation, and responsive design. Compatible with Luma, Blank, and Hyvä themes.
B2B customer registration with admin approval workflow for Magento 2 / Adobe Commerce. Adds a dedicated B2B signup form with company data, VAT ID, and reCAPTCHA, holds new accounts in a pending state until a store admin reviews them, and triggers separate transactional emails for the customer and the shop owner.
Turn an existing module into recurring revenue.
If you already maintain a Magento 2 module on GitHub or GitLab, listing it on Packagento takes about five minutes. We mirror your tags, handle distribution signing, and route paid licenses through Stripe Connect, so you can keep shipping the way you already do.