konekt/customer
Konekt Customer is a Laravel package for managing customer records, including personal and organizational details, addresses, and related data. It provides ready-to-use models and migrations to add customer management to your app.
Install the module and register it with Concord before writing any application code:
composer require konekt/customer
Add the module to config/concord.php:
'modules' => [
Konekt\Customer\Providers\ModuleServiceProvider::class,
],
Migrations run through Concord's module loader, so php artisan migrate is enough — you do not need to publish anything to get the base tables. If you do want to customize schema or models, publish the config first (vendor:publish --tag=concord or the module-specific tag) so you have something to override.
Where to look first: src/Models (the Customer and Address models), src/Contracts (the interfaces you should depend on), and src/Traits (the Customer/Address behaviour you can graft onto your own models). The service provider is the quickest way to see what's bound and what's registerable.
First use case: create a customer and attach an address.
use Konekt\Customer\Models\Customer;
use Konekt\Customer\Models\Address;
$customer = Customer::create([
'firstname' => 'Jane',
'lastname' => 'Doe',
'email' => '[email protected]',
]);
$customer->addresses()->create([
'name' => 'HQ',
'country_id' => 'US',
'city' => 'Austin',
'address' => '1 Main St',
]);
That is the core loop the package exists to support: a customer with one or more typed addresses. Everything else (billing vs. shipping, customer types) is layered on top of this.
Depend on contracts, not models. Konekt packages ship Contracts\Customer / Contracts\Address interfaces wired up via Concord's container bindings. Inject these into services and controllers so you can swap the concrete class later without touching call sites:
public function __construct(private \Konekt\Customer\Contracts\Customer $customer) {}
Override models through Concord bindings, not by forking. If you need extra columns or behaviour, subclass the model and register the binding in your own service provider:
$this->app->bind(
\Konekt\Customer\Contracts\Customer::class,
\App\Models\Customer::class
);
Your subclass can still extend the package model and add traits. This is the intended extension point — it keeps package upgrades clean.
Use the addressable association for polymorphic address owners. Addresses attach to the customer via a morph relation, so the same address table can back orders, invoices, or other entities. Always go through the relation ($customer->addresses()->create(...)) rather than creating orphan Address records — the morph keys are set for you.
Leverage address types for billing/shipping semantics. The package models address types as records (not a PHP enum), so you can add domain-specific types via migration/seed rather than editing code. Query by type when rendering checkout or invoice blocks:
$billing = $customer->addresses()->where('type_id', 'billing')->first();
Compose with the trait rather than re-implementing. If your existing User or Company model should be a customer, use the package trait to borrow fields and relations instead of duplicating the schema. This is the cheapest integration path when you already have an identity model and just need addresses on it.
Treat it as the data layer, not the feature. The package has no auth, no UI, no checkout flow. Pair it with your own controllers/resources; it earns its keep as a well-typed schema that other Konekt modules (orders, invoicing) can speak to.
config/concord.php means no migrations, no bindings, and confusing "class not found" errors. Check php artisan concord:modules to confirm it's loaded.database/migrations and leaving the module registered will cause duplicate-table errors on fresh installs.'billing') without seeding that type will silently produce empty lookups. Seed address types in a seeder and validate against them.Address::create() calls, addressable_id/addressable_type stay null and $customer->addresses won't see them. Use the relation.src/ when in doubt. Pin the minor version in composer.json and read the changelog before upgrading — the Konekt modules occasionally shift contracts between releases.$model->getMorphClass() and the type_id on the rows — those two mismatches account for most "it should work" moments with this package.How can I help you explore Laravel packages today?