← Back to the developers overview
Extension package
Directory layout, manifest, translations and building the ZIP with package_artifact.py.
An extension is a PHP package with a manifest. The official extensions (Checkbox, Nova Poshta, Stripe) in laracart-extensions/official are working examples.
my-extension/
manifest.json # the manifest (see “Extension manifest fields”)
composer.json # PSR-4, e.g. "Acme\\Delivery\\": "src/"
src/ # PHP classes, including the entrypoints
translations.json # which translation catalogue serves which locale
lang/uk.json
lang/en.json
assets/ # optional - translations.json: {"manifest_contract_version": 1, "namespace": "extension.<code>", "catalogs": {"uk": "lang/uk.json", "en": "lang/en.json"}} — 1 to 50 locales, data only.
- Translation keys look like extension.<code>.name, extension.<code>.settings.api_key and so on.
- Extension tables are described by *.migration.json files (create_table, add_columns, add_indexes); SQL and PHP migrations are not accepted — the platform runs them itself in the extension’s own namespace.
- Do not create extension.json in the source tree: the packager generates it.
Build and verify the archive:
python scripts/package_artifact.py build ./my-extension dist ./private-key.pem my-key-id
python scripts/package_artifact.py verify dist/<code>-<version>.zip dist/<code>-<version>.manifest.json dist/<code>-<version>.checksum ./public-key.pem - The packager builds a deterministic ZIP and puts extension.json — the canonical manifest — inside it.
- manifest.json, .git, vendor, node_modules, dist, __pycache__, .DS_Store and symlinks never go into the archive.
- Output: <code>-<version>.zip, .checksum (SHA-256) and .manifest.json — the publication JSON you attach to the submission.
- OpenSSL 3.x is required (set LARACART_OPENSSL_BIN if it is not on PATH).