{"id":28656071,"url":"https://github.com/offline-gmbh/oc-microcart-plugin","last_synced_at":"2025-08-20T12:11:36.940Z","repository":{"id":35045110,"uuid":"198855793","full_name":"OFFLINE-GmbH/oc-microcart-plugin","owner":"OFFLINE-GmbH","description":":shopping_cart: Simple shopping cart component for October CMS","archived":false,"fork":false,"pushed_at":"2022-04-07T09:39:22.000Z","size":126,"stargazers_count":17,"open_issues_count":6,"forks_count":12,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-06-12T02:16:35.471Z","etag":null,"topics":["ecommerce","octobercms","octobercms-plugin","shopping-cart"],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/OFFLINE-GmbH.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-07-25T15:21:21.000Z","updated_at":"2025-06-09T06:47:31.000Z","dependencies_parsed_at":"2022-08-08T04:01:23.367Z","dependency_job_id":null,"html_url":"https://github.com/OFFLINE-GmbH/oc-microcart-plugin","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/OFFLINE-GmbH/oc-microcart-plugin","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OFFLINE-GmbH%2Foc-microcart-plugin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OFFLINE-GmbH%2Foc-microcart-plugin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OFFLINE-GmbH%2Foc-microcart-plugin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OFFLINE-GmbH%2Foc-microcart-plugin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/OFFLINE-GmbH","download_url":"https://codeload.github.com/OFFLINE-GmbH/oc-microcart-plugin/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OFFLINE-GmbH%2Foc-microcart-plugin/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259606992,"owners_count":22883565,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ecommerce","octobercms","octobercms-plugin","shopping-cart"],"created_at":"2025-06-13T08:10:14.676Z","updated_at":"2025-06-13T08:10:15.519Z","avatar_url":"https://github.com/OFFLINE-GmbH.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# oc-microcart-plugin\n\n\u003e The `OFFLINE.MicroCart` plugin aims to provide simple shopping cart and payment features.\n\nThis plugin is meant for projects where simple items are sold online (Tickets, Coupons, etc).\nYou will have to implement the \"item part\" (like a `Ticket` model) yourself. You can use\nthe plugin as cart and payment solution.\n\n## Features\n\nThe `OFFLINE.MicroCart` plugin provides the following features:\n\n* A `Cart` model with a nice API to add and remove `CartItems`\n* A `Cart` component base, that is meant to be extended by you\n* `Stripe`, `PayPal` and `SIX SaferPay` payment integrations\n* Support to add custom payment gateways\n* Numerous events for you to hook into \n\nIt **does not** provide any of these features:\n\n* Product data management\n* E-Mail notifications \n* Multi currency support\n* Stock management\n* Shipping rules\n* ... and lots of other extended eCommerce features\n\nIf you are looking for a fully featured eCommerce solution for October CMS\ncheck out [OFFLINE.Mall](https://github.com/OFFLINE-GmbH/oc-mall-plugin).\n\n## Getting up and running\n\n### Create your own plugin that extends MicroCart\n\nThe MicroCart plugin is meant to be extended by your own plugins.\nRefer to [the official October CMS docs](https://octobercms.com/docs/plugin/extending)\nfor a list of all extension possibilities.\n\n```bash\nphp artisan create:plugin YourVendor.PluginName\n```\n\n### Backend menu\n\nThe plugin does by default not register any backend menu items. You can use the\nfollowing snippet in your own `Plugin.php` to use the default orders overview.\n\n```php\n    public function registerNavigation()\n    {\n        return [\n            'main-menu-item' =\u003e [\n                'label'        =\u003e 'Your Plugin', // Your label\n                'url'          =\u003e \\Backend::url('offline/microcart/carts'),\n                'iconSvg'      =\u003e 'plugins/offline/microcart/assets/icon.svg',\n            ],\n        ];\n    }\n``` \n\n### Cart component\n\nThe plugin does not register any components but it provides you with a `Cart` base \ncomponent that you can extend.\n\nSimply register your own component and build from there.\n\n```bash\nphp artisan create:component YourVendor.PluginName Cart\n```\n\nRegister your component in your `Plugin.php`.\n\n```php\n    public function registerComponents()\n    {\n        return [\n            \\YourVendor\\YourPlugin\\Components\\Cart::class =\u003e 'cart',\n        ];\n    }\n```\n\nMake sure the component extends MicroCart's base component.\n\n```php\n\u003c?php namespace YourVendor\\YourPlugin\\Components;\n\nuse OFFLINE\\MicroCart\\Models\\CartItem;\nuse OFFLINE\\MicroCart\\Classes\\Payments\\PaymentRedirector;\n\nclass Cart extends \\OFFLINE\\MicroCart\\Components\\Cart\n{        \n    public function onRun()\n    {\n        // An off-site payment has been completed. Important, this code\n        // needs to be present if you are using PayPal or Six. \n        if ($type = request()-\u003einput('return')) {\n            return (new PaymentRedirector($this-\u003epage-\u003epage-\u003efileName))-\u003ehandleOffSiteReturn($type);\n        }\n\n        // Do something.\n    }\n\n    public function onAdd()\n    {\n        $item           = new CartItem();\n        $item-\u003ename     = 'Your product';\n        $item-\u003equantity = random_int(1, 4);\n        $item-\u003eprice    = 100.00;\n\n        $this-\u003ecart-\u003eadd($item);\n\n        return $this-\u003erefreshCart();\n    }\n}\n```\n\nTo modify validation rules and messages take a look at the `getValidationRules`, `getFieldNames`\nand `getValidationMessages` methods on the base `Cart` class.\n\nCopy [the default partials](./components/cart) from MicroCart's base component to your own component.\nModify them as needed.\n\n```bash\ncp -rv plugins/offline/microcart/components/cart/* plugins/yourvendor/yourplugin/components/cart/\n```\n\n#### Updating the cart partials\n\nYou can `return $this-\u003erefreshCart();` from your Cart component's methods to refresh the cart display. \n\n### Using payment providers\n\nThere are three payment providers supported out-of-the-box:\n\n* PayPal (`composer require omnipay/stripe`)\n* Stripe (`composer require omnipay/paypal`)\n* Six SaferPay (`composer require ticketpark/saferpay-json-api`)\n\nRun the composer commands beside each provider you plan to use. You can configure the\nproviders via October's backend settings.\n\n### Custom payment providers\n\nTo register a custom `PaymentProvider` create a class that extends MicroCart's PaymentProvider class. [\nCheck out the existing providers](./classes/payments) to get some inspiration on how to create your own.\n\n```php\n\u003c?php\n\nnamespace YourVendor\\YourPlugin\\Classes;\n\nuse OFFLINE\\MicroCart\\Classes\\Payments\\PaymentProvider;\n\nclass YourCustomProvider extends PaymentProvider\n{\n    // Implement all abstract methods.\n}\n```\n\nIn your `Plugin.php` register this custom provider by returning them from a `registerPaymentProviders` method.\n\n```php\nuse OFFLINE\\MicroCart\\Classes\\Payments\\PaymentGateway;\n\nclass Plugin extends PluginBase\n{\n    public function registerPaymentProviders()\n    {\n        return [\n            new YourCustomProvider(),\n        ];\n    }\n}\n```  \n\n### Link your model to cart items\n\nThe easiest way to link a model to a `CartItem` is to add a simple `belongsTo` relationship.\n\n```php\n// Voucher is the thing we are selling (the CartItem)\nclass Voucher extends Model\n{\n    public $belongsTo = [\n        'cartitem' =\u003e CartItem::class\n    ];\n}\n``` \n\n## API\n\n### Cart\n\n#### Get the user's cart\n\n```php\n// This cart will be unique to the current user.\n$cart = Cart::fromSession();\n```\n\n#### Add an item to the cart\n\n```php\n$item           = new CartItem();\n$item-\u003ename     = 'An item'; // The only required field\n$item-\u003equantity = 2;\n$item-\u003eprice    = 20.00;\n\n$cart-\u003eadd($item);\n```\n\n#### Ensure an item is in the cart\n\n```php\n$item = new CartItem(['name' =\u003e 'Shipping fee', 'kind' =\u003e CartItem::KIND_SERVICE]);\n\n// A code property is required! A product with the specified\n// code is ensured to be present in the Cart.\n$item-\u003ecode = 'shipping'; \n\n// ensure the item is in the cart. If it's not, it will be added.\n$cart-\u003eensure($item);\n// A second call will not add the item again.\n$cart-\u003eensure($item);\n// You can force a new quantity by passing a second parameter.\n$cart-\u003eensure($item, 4);\n```\n\n\n#### Remove an item from the cart\n\n```php\n$item = new CartItem(['name' =\u003e 'An item']);\n\n// You can remove an item by passing in a CartItem object or an id.\n$cart-\u003eremove($item);\n$cart-\u003eremove($item-\u003eid);\n```\n\n#### Remove all items with a given code from the cart\n\n```php\n$item = new CartItem(['name' =\u003e 'Shipping fee', 'code' =\u003e 'shipping', 'kind' =\u003e CartItem::KIND_SERVICE]);\n\n// Removes all items with a given code (reverse of the `ensure` method).\n$cart-\u003eremoveByCode('shipping');\n```\n\n\n#### Update an item's quantity\n\n```php\n$item = new CartItem(['name' =\u003e 'An item']);\n\n// You can set the quantity by passing in a CartItem object or an id.\n$cart-\u003esetQuantity($item, 4);\n$cart-\u003esetQuantity($item-\u003eid, 4);\n```\n\n#### Service fees and discounts\n\nSet the `kind` attribute to either `CartItem::KIND_SERVICE` or `CartItem::KIND_DISCOUNT`\nif the item is a service fee (Shipping, Handling) or a discount. \nUse the `ensure` method to make sure it's only added once to the Cart.\n\n\n```php\n$item = new CartItem(['name' =\u003e 'Shipping fee', 'kind' =\u003e CartItem::KIND_SERVICE, 'price' =\u003e 10]);\n\n// The code is required to use the `ensure` method.\n$item-\u003ecode = 'shipping'; \n\n$cart-\u003eensure($item);\n\n\n$item = new CartItem(['name' =\u003e 'Discount', 'kind' =\u003e CartItem::KIND_DISCOUNT, 'price' =\u003e -100]);\n$item-\u003ecode = 'discount'; \n\n$cart-\u003eensure($item);\n```\n\n#### Access cart contents\n\nYou can access all cart items using the `$cart-\u003eitems` relation.\n\nYou also have access to filtered `list_items`, `service_fees` and `discounts` \nproperties that only contain the given item types.\n\n```php\n$item     = new CartItem(['name' =\u003e 'A product']);\n$shipping = new CartItem(['name' =\u003e 'Shipping fee', 'kind' =\u003e CartItem::KIND_SERVICE]);\n$discount = new CartItem(['name' =\u003e 'Discount',     'kind' =\u003e CartItem::KIND_DISCOUNT]);\n\n$cart-\u003eaddMany($item, $shipping, $discount);\n\n$cart-\u003elist_items-\u003efirst()   === $item;     // true\n$cart-\u003eservice_fees-\u003efirst() === $shipping; // true\n$cart-\u003ediscounts-\u003efirst()    === $discount; // true\n```  \n\n#### Print the customer's address\n\nAfter a `Cart` checkout has been successful, you can use the following helpers\nto get the customer's address as an array or an escaped HTML string.\n\n```php\n$cart-\u003egetShippingAddressArray();\n// ['Company', 'Firstname Lastname', ...];\n\n$cart-\u003egetBillingAddressHtml();\n// Company\u003cbr /\u003e\n// Firstname Lastname\u003cbr /\u003e\n// Street 123\u003cbr /\u003e\n// ZIP City\n\n$cart-\u003egetBillingAddressHtmlZipReversed();\n// Company\u003cbr /\u003e\n// Firstname Lastname\u003cbr /\u003e\n// Street 123\u003cbr /\u003e\n// City ZIP\n```\n\n### CartItem\n\n#### Create an item\n\n```php\n// Short format\n$item = new CartItem(['name' =\u003e 'An item']);\n\n// Or long format\n$item = new CartItem();\n$item-\u003ename = 'An item';\n$item-\u003edescription = 'The description to this item';\n$item-\u003eprice = 20.00; // Includes tax by default.\n$item-\u003equantity = 10;\n$item-\u003emeta = [\n    'any' =\u003e 'additional',\n    'data' =\u003e true,\n];\n// $item-\u003etax_id = 2;           // If not specified the default tax will be used. \n// $item-\u003etax_free = true;      // Don't add taxes to this item, not even the default tax. \n// $item-\u003eis_before_tax = true; // The specified price does not include taxes. \n```\n\n#### Access item information\n\n```php\n// Create an example item\n$item           = new CartItem(['name' =\u003e 'An item']);\n$item-\u003eprice    = 10.00;\n$item-\u003equantity = 2;\n$item-\u003etax_id   = 1; // 10% tax\n\n// Access the item's information\n$item-\u003eprice;        // 10.00\n$item-\u003equantity;     // 2\n$item-\u003esubtotal;     // 20.00 =\u003e price * quantity\n$item-\u003etax_amount;   //  2.00 =\u003e 10 % on price \n$item-\u003etotal;        // 22.00 =\u003e (price * quantity) + tax_amount\n```\n\n\n### Money\n\nThere is a `Money` singleton class available to format cents as a string.\nA `microcart_money` Twig helper is registered as well.\n\n```php\nMoney::instance()-\u003eformat(12000); // 120.00 USD\n\n// or in Twig\n{{ 120000 | microcart_money }}   // 120.00 USD\n```\n\n#### Change the default money formatter\n\nYou can register your own formatter function by adding the following code\nto your Plugin's `register` method.\n\n```php\n    public function register()\n    {\n        \\Event::listen('offline.microcart.moneyformatter', function () {\n            return function ($cents): string {\n                return 'Your custom implementation to format: ' . $cents;\n            };\n        });\n    }\n```\n\n## Events\n\n### Cart\n\n#### `offline.microcart.cart.beforeAdd`\n\nFired before an item is added to the Cart. It receives the following arguments:\n\n* `$cart`: the `Cart` of the current user \n* `$item`: the `CartItem` being added \n\n#### `offline.microcart.cart.afterAdd`\n\nFired after an item has been added to the Cart. It receives the following arguments:\n\n* `$cart`: the `Cart` of the current user \n* `$item`: the `CartItem` added \n\n#### `offline.microcart.cart.beforeRemove`\n\nFired before an item is removed from the Cart. It receives the following arguments:\n\n* `$cart`: the `Cart` of the current user \n* `$item`: the `CartItem` being removed \n\n#### `offline.microcart.cart.afterRemove`\n\nFired after an item has been removed from the Cart. It receives the following arguments:\n\n* `$cart`: the `Cart` of the current user \n* `$item`: the `CartItem` removed \n\n#### `offline.microcart.cart.quantityChanged`\n\nFired after the quantity of a cart item has changed.\n\n* `$cart`: the `Cart` of the current user \n* `$item`: the `CartItem` that was updated\n\n### Checkout\n\n#### `offline.microcart.checkout.succeeded`\n\nFired after a checkout was successful.\n\n* `$result`: a `PaymentResult` instance\n\n#### `offline.microcart.checkout.failed`\n\nFired after a checkout has failed.\n\n* `$result`: a `?PaymentResult` instance (nullable)  \n\n#### `offline.microcart.checkout.cancelled`\n\nFired after a checkout has been cancelled.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foffline-gmbh%2Foc-microcart-plugin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foffline-gmbh%2Foc-microcart-plugin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foffline-gmbh%2Foc-microcart-plugin/lists"}