---
title: "Addresses for Laravel — docs | Roundly"
description: "Developer docs for Addresses for Laravel: polymorphic addresses, typed address types, primary addresses, ISO country codes, events and test helpers."
url: https://roundly-consulting.com/open-source/docs/addresses-for-laravel
language: en
---

[All packages](https://roundly-consulting.com/open-source.md)

Open source

# Addresses for Laravel

Install

`composer require roundly-consulting/addresses-for-laravel`

Requires: PHP ^8.4 · Laravel ^12.0|^13.0

[GitHub](https://github.com/roundly-consulting/addresses-for-laravel) [Packagist](https://packagist.org/packages/roundly-consulting/addresses-for-laravel) [Donate (opens in a new tab)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Patreon](https://www.patreon.com/cw/roundly)

## Overview

Addresses for any Eloquent model, native to Laravel. Add the HasAddresses trait and attach as many billing, shipping, home or office addresses as you need through one polymorphic addresses table — created with a fluent builder or a DTO, typed by an AddressType enum, with at most one primary address per type, promoted atomically, and ISO country codes normalised on the way in. Query scopes, lifecycle events, an API resource and test helpers are included. MIT-licensed and built only on Laravel and Roundly’s own package toolkit — no third-party dependencies, no network calls.

### What you get

#### Addresses on any model

One trait and one polymorphic table give any Eloquent model billing, shipping or office addresses — for bigint, UUID or ULID owners.

#### Typed address types

An AddressType enum — default, billing, shipping, home, work, office — with UI labels. No loose string types anywhere in the API.

#### One primary per type

Promoting an address demotes its siblings atomically, under a lock on the owner + type group; another owner’s or a deleted address is refused.

#### Facade, DI or actions

Addresses::for($customer)->new()->in(…)->at(…)->save() reads like a sentence; inject AddressManager or run an action for the same result.

#### ISO country normalisation

Codes are trimmed, upper-cased and shape-checked on write. Plug in your own CountryResolver for names and geocoding — no network calls.

#### Events, scopes & API resource

Four lifecycle events, primary/ofType/inCountry query scopes and a stable AddressResource for JSON APIs.

#### Recording fake & test helpers

Addresses::fake() records every write without touching the database, plus assertHasAddress(), assertPrimaryAddress() and an AddressFactory.

### Documentation

#### [Installation](https://roundly-consulting.com/open-source/docs/addresses-for-laravel/installation.md)

Install via Composer, publish and run the addresses migration (set a UUID or ULID key type first), and optionally publish config/addresses.php.

#### [Configuration](https://roundly-consulting.com/open-source/docs/addresses-for-laravel/configuration.md)

Every config key and its default — the address model, owner key type, default type, country normalisation, resolver and facade alias.

#### [Database schema & key types](https://roundly-consulting.com/open-source/docs/addresses-for-laravel/database-schema.md)

The addresses table column by column, and how key\_type shapes the polymorphic owner column for bigint, UUID or ULID models.

#### [The HasAddresses trait](https://roundly-consulting.com/open-source/docs/addresses-for-laravel/has-addresses.md)

Add HasAddresses to any Eloquent model for a polymorphic addresses relation plus create, read and primary-address helpers.

#### [Address types](https://roundly-consulting.com/open-source/docs/addresses-for-laravel/address-types.md)

The AddressType enum — six cases with UI labels — and how to convert untrusted strings from requests safely.

#### [The Addresses facade](https://roundly-consulting.com/open-source/docs/addresses-for-laravel/facade.md)

Addresses::for($owner) returns an owner’s address book for any model; update, delete and countryName work on a single address.

#### [DI and actions](https://roundly-consulting.com/open-source/docs/addresses-for-laravel/without-facade.md)

Skip the facade: inject AddressManager or run one of the four actions directly — the facade method → action map.

#### [AddressData & CreateAddressAction](https://roundly-consulting.com/open-source/docs/addresses-for-laravel/dto-and-actions.md)

Build writes with the AddressData DTO — make(), its defaults and the default\_type fallback — or createAddress(), and run CreateAddressAction on any model.

#### [Fluent builder](https://roundly-consulting.com/open-source/docs/addresses-for-laravel/fluent-builder.md)

Create addresses with Addresses::for()->new() or newAddress() — a readable PendingAddress chain that refuses incomplete addresses.

#### [Reading addresses](https://roundly-consulting.com/open-source/docs/addresses-for-laravel/reading-addresses.md)

Fetch all addresses, the first or primary address of a type, a typed collection or a quick existence check.

#### [Primary addresses](https://roundly-consulting.com/open-source/docs/addresses-for-laravel/primary-addresses.md)

One primary address per owner and type — promote, demote, set it on create and guard against another owner’s address.

#### [Query scopes](https://roundly-consulting.com/open-source/docs/addresses-for-laravel/query-scopes.md)

Filter addresses with the primary(), ofType() and inCountry() scopes — on the model, on any owner’s relation, or combined.

#### [The Address model](https://roundly-consulting.com/open-source/docs/addresses-for-laravel/address-model.md)

Attributes, casts, the owner relation, JSON meta and the formatted() one-line label on the Address model.

#### [Updating & deleting](https://roundly-consulting.com/open-source/docs/addresses-for-laravel/updating-deleting.md)

Update with Addresses::update() and a full AddressData, soft-delete and restore addresses, and clean up when an owner goes.

#### [Country codes & resolvers](https://roundly-consulting.com/open-source/docs/addresses-for-laravel/countries.md)

ISO country normalisation on every write, plus an optional CountryResolver for names and geocoding — no bundled data, no network calls.

#### [Events](https://roundly-consulting.com/open-source/docs/addresses-for-laravel/events.md)

AddressCreated, AddressUpdated, AddressDeleted and PrimaryAddressChanged — when each one fires, why they wait for the commit, and how to listen.

#### [API resource](https://roundly-consulting.com/open-source/docs/addresses-for-laravel/api-resource.md)

AddressResource renders an address for JSON APIs with a stable shape — lines, country, primary flag, formatted label and meta.

#### [Custom address model](https://roundly-consulting.com/open-source/docs/addresses-for-laravel/custom-model.md)

Swap in your own Address subclass through config to add scopes, relations or casts — every package path follows it.

#### [Exceptions](https://roundly-consulting.com/open-source/docs/addresses-for-laravel/exceptions.md)

One AddressesException base and five typed exceptions — incomplete address, invalid country, foreign address, deleted address and invalid type.

#### [Testing](https://roundly-consulting.com/open-source/docs/addresses-for-laravel/testing.md)

The recording Addresses::fake(), InteractsWithAddresses assertions, the AddressFactory with billing, shipping and primary states, and a Pest example.

#### [Requirements](https://roundly-consulting.com/open-source/docs/addresses-for-laravel/requirements.md)

PHP 8.4+ and Laravel 12 or 13 — no PHP extensions, no third-party dependencies and no network calls.

## Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

[More ways to support, including crypto](https://roundly-consulting.com/support-us.md)

By donating, you agree to our [donation terms](https://roundly-consulting.com/donation-terms.md).

[Support our open source work (opens in a new tab)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Join us on Patreon (opens in a new tab)](https://www.patreon.com/cw/roundly)

## Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.

[Get a quote in 48 hours](https://roundly-consulting.com/contact.md) [Browse all packages](https://roundly-consulting.com/open-source.md)
