mews/laravel-pos
A Laravel package from Mews for integrating point-of-sale capabilities into your app, with configuration, service bindings, and API clients to connect Laravel applications to Mews POS services.
This is a source-first package: 111 stars, zero dependents, and a terse README, so budget the first hour for reading src/ rather than for reading docs.
Resolve the name before you install. The package name in your metadata is mews/laravel-pos, but the repository is mewebstudio/laravel-pos. Do not guess the Composer name:
composer show -a mews/laravel-pos # verify the vendor/name resolves
composer show -a mewebstudio/laravel-pos # likely the real one
Confirm before adding to composer.json; a mismatch here will waste the whole onboarding.
Install and inspect what was auto-registered.
composer require mews/laravel-pos
php artisan about # provider should appear under "packages"
Open vendor/mews/laravel-pos/composer.json and read extra.laravel.providers / extra.laravel.aliases. That tells you the facade name and the service provider class you will reference in every vendor:publish call below.
Publish, then look at what you got.
php artisan vendor:publish --provider="Mews\\Pos\\PosServiceProvider"
Run it interactively (no --tag) the first time so you see every publish group: config, migrations, views, lang. The file list is the package's surface area.
Trace one path end to end before writing any application code: provider boot() → routes file → controller → model → migration. If the package ships routes, php artisan route:list --path=pos gives you the fastest map of its HTTP surface.
First use case: get the smallest possible round trip working — migrate, create one record through whatever the package exposes (facade, model, or route), read it back. Only then wire it into your domain. Don't start by integrating with your existing Product/Order models.
Wrap, don't sprinkle. Treat the package's facade and models as third-party infrastructure. Put a thin application-level service or repository in front of them:
final class PosGateway
{
public function __construct(private Pos $pos) {}
public function checkout(array $payload): PosReceipt
{
return $this->pos->checkout($payload);
}
}
Bind this in a service provider and type-hint PosGateway everywhere. When the package is abandoned or you outgrow it — a real risk at zero dependents — you have one file to rewrite.
Config over code. Anything the package makes configurable, configure it in config/pos.php and drive it from .env. Resist editing published migrations or views as your primary customization; instead:
composer update instead of a merge conflict.view('pos::receipt', ...) → publish only the file you changed into resources/views/vendor/pos/).lang/vendor/pos/.Contain the HTTP surface. If the package registers routes, wrap them behind your own middleware group in RouteServiceProvider or bootstrap/app.php — auth, throttle, and a route prefix. Package routes are commonly registered without auth; assume they are public until you've read the route file.
Test at the boundary. Use RefreshDatabase and the package's migrations in your test suite so CI catches schema drift on upgrade. Assert against your PosGateway contract, not against package internals, so refactors don't cascade.
Integration tips for a POS domain specifically: money should cross the boundary as integer minor units or a Money value object, never floats — check what the package's migrations declare for amount columns before you build on them. Timezone-sensitive receipt/transaction timestamps are the second thing to check; store UTC, render local.
composer.json require block against your Laravel and PHP versions, and check whether the release date implies support for your framework major. Pin the version ("mews/laravel-pos": "1.0.*") so a surprise tag doesn't break production."repositories": [{"type": "vcs", ...}]). You get a patch path the day the upstream goes quiet, at near-zero cost.php artisan about), then check whether the facade's accessor resolves to a singleton you've already bound. A silently empty config('pos') almost always means the config was never published.vendor:publish overwrites. Published files are yours; re-publishing replaces them. Commit them to git immediately after publishing so you can diff on the next upgrade.How can I help you explore Laravel packages today?