NewWe open-sourced 50+ Laravel packages
Custom AI apps, agents and automation — Roundly ConsultingRoundly
All packages
Contacts for Laravel

Structured addresses

A Contact is Addressable, so it holds a billing, physical or mailing address book through addresses-for-laravel. The loose value string keeps working as a fallback:

use RoundlyConsulting\Addresses\DataTransferObjects\AddressData;
use RoundlyConsulting\Addresses\Enums\AddressType;

$contact->addAddress(AddressData::make(
    city: 'Bratislava', street: 'Hlavna 1', postalCode: '81101',
    countryIso: 'SK', type: AddressType::Billing, isPrimary: true,
));

$contact->primaryAddress();                       // the primary Address
$contact->addressesOfType(AddressType::Billing);  // typed lookup
$contact->formattedAddress();                     // one-line render, falls back to value
  • addresses(), addAddress(AddressData), primaryAddress(?AddressType), addressesOfType(AddressType), setPrimaryAddress(Address) — from the addresses package’s HasAddresses trait.
  • formattedAddress() — the primary address’s one-line render, or the contact’s value when none is attached.
  • AddressType cases: Default, Billing, Shipping, Home, Work, Office.

Creating contact and address together

// Build an address-type contact and its structured Address in one call:
Contacts::for($owner)
    ->structuredAddress([
        'city' => 'Vienna', 'street' => 'Ring 3',
        'postalCode' => '1010', 'countryIso' => 'AT',
        'type' => AddressType::Billing,
    ])
    ->add();

// Or from the owner directly:
$owner->addStructuredAddress(AddressData::make(
    city: 'Bratislava', street: 'Hlavna 1', postalCode: '81101', countryIso: 'SK',
), label: 'Main');

structuredAddress() accepts an AddressData or an array (city, street, postalCode or postal_code, countryIso or country_iso, name, type, isPrimary). A missing or unrecognized type is left to the host’s addresses.default_type, exactly as an address created through the addresses package. On add() the contact’s value mirrors the address’s one-line render, so existing readers keep working.

A structured address is only accepted on an address contact — anything else throws InvalidContactValue. Country codes are validated by the addresses package — an unknown country throws its InvalidCountryException. Soft-deleting a contact trashes its addresses with it, restore() brings them back and forceDelete() removes them for good.

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

By donating, you agree to our donation terms.

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.