PHPackages                             payload-interop/payload-interop - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. payload-interop/payload-interop

ActiveLibrary

payload-interop/payload-interop
===============================

An interoperable Domain Payload Object specification.

1.0.0(6y ago)3978.2k↓26.4%37MITPHP

Since Feb 10Pushed 2y ago10 watchersCompare

[ Source](https://github.com/payload-interop/payload-interop)[ Packagist](https://packagist.org/packages/payload-interop/payload-interop)[ RSS](/packages/payload-interop-payload-interop/feed)WikiDiscussions 1.x Synced 1mo ago

READMEChangelog (1)DependenciesVersions (2)Used By (7)

payload-interop
===============

[](#payload-interop)

The `payload-interop` project defines an interoperable interface for reading the domain *result* and domain *status* from a *Domain Payload Object*, in a way that is independent of any particular user interface.

Purpose
-------

[](#purpose)

The *Domain Payload Object* pattern was first described by Vaughn Vernon at [https://vaughnvernon.co/?page\_id=40](https://web.archive.org/web/20170620063845/https://vaughnvernon.co/?page_id=40)

Whereas a *Data Transfer Object* provides *properties* found on domain objects, a *Domain Payload Object* provides *entire domain objects*. Its purpose is to transport those domain objects across the architectural boundary from the domain layer to the user interface layer.

The *Domain Payload Object* is **not** for intra-domain use. It is only for transporting a domain result across the domain layer boundary back to the calling code, typically the user interface layer.

Further, the *Domain Payload Object* is independent of any particular user interface. As part of the domain layer, it should have no knowledge of HTTP or CLI contexts.

For more usage notes, please refer to [USING.md](./USING.md).

This project defines only a reading interface, so that any user interface code can know how to get both the result and the status out of the *Domain Payload Object*.

This project does not define a writing or mutation interface. Creation and manipulation of *Domain Payload Objects* are core application concerns, not user interface concerns. The domain-specific nature places it outside the scope of an interoperability specification.

Summary
-------

[](#summary)

Research on [Packagist](http://packagist.org) and elsewhere revealed a number of existing [*Domain Payload Object* implementations](./IMPLEMENTATIONS.md). The commonalities discovered by this research are codified in the [`DomainPayload` interface](./src/DomainPayload.php) and the [`DomainStatus` constants](./src/DomainStatus.php).

### Domain Result

[](#domain-result)

All of the reference implementations provided functionality to get the domain results or domain data for presentation. It was noted that these results included not only domain objects, but also the input as received by the domain, error or validation messages, exception objects, and so on.

As such, this project expands the semantics of the *Domain Payload Object*definition to include any data produced by the domain layer that might be needed for presentation by the user interface.

This commonality is reflected in the `DomainPayload::getResult() : array`method.

Having found that commonality, this project encourages implementors to provide additional reading methods typhinted to their respective domain objects, to enable better static analysis and automated refactoring. In doing so, implementors may find themselves with multiple *Domain Payload Object* classes, one for each domain interaction (or family of related interactions).

### Domain Status

[](#domain-status)

The reference implementations also include functionality to discover the "status" of the attempted domain activity. That is, whether the activity was successful or not, and what kind of success or failure was encountered.

There was a wide range of status values, occasionally integers but more frequently strings, defined as constants. Some of these values obviously mimicked HTTP user interface response codes. Less often, statuses were indicated by separate classes, rather than by a constant value.

After normalizing and collating the different statuses across the reference implementations, it turned out there were several that were both user-interface agnostic and common to most or all implementations. These were most frequently string valued constants.

This commonality is reflected in the `DomainPayload::getStatus() : string`method, along with the `DomainStatus` constants:

- `ACCEPTED`
- `CREATED`
- `DELETED`
- `ERROR`
- `FOUND`
- `INVALID`
- `NOT_FOUND`
- `PROCESSING`
- `SUCCESS`
- `UNAUTHORIZED`
- `UPDATED`

Implementors may add other status values as appropriate for their domain.

Implementation Notes
--------------------

[](#implementation-notes)

A basic, bare-bones implementation might look something like this:

```
namespace Application;

use PayloadInterop\DomainPayload;

class Payload implements DomainPayload
{
    protected $status;

    protected $result;

    public function __construct(string $status, array $result)
    {
        $this->status = $status;
        $this->result = $result;
    }

    public function getStatus() : string
    {
        return $this->status;
    }

    public function getResult() : array
    {
        return $this->result;
    }
}
```

A domain layer *Application Service*, *Transaction Script*, or *Use Case* might use it like so:

```
namespace Application;

use Domain\Exception\InvalidInput;
use Domain\Forum\ForumRepository;
use Exception;
use PayloadInterop\DomainStatus;

class CreateForumTopic
{
    protected $forumRepository;

    public function __construct(ForumRepository $forumRepository)
    {
        $this->forumRepository = $forumRepository;
    }

    public function __invoke(string $title, string $body) : Payload
    {
        try {

            $topic = $this->forumRepository->newTopic($title, $body);
            $this->forumRepository->save($topic);
            return new Payload(DomainStatus::CREATED, [
                'topic' => $topic
            ]);

        } catch (InvalidInput $e) {

            return new Payload(DomainStatus::INVALID, [
                'input' => [
                    'title' => $title,
                    'body' => $body,
                ]],
                'messages' => $e->getMessages()
            );

        } catch (Exception $e) {

            return new Payload(DomainStatus::ERROR, [
                'exception' => $e
            ]);

        }
    }
}
```

###  Health Score

38

—

LowBetter than 85% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity42

Moderate usage in the ecosystem

Community23

Small or concentrated contributor base

Maturity56

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 71.4% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~1339 days

Total

2

Last Release

950d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/25754?v=4)[Paul M. Jones](/maintainers/pmjones)[@pmjones](https://github.com/pmjones)

---

Top Contributors

[![pmjones](https://avatars.githubusercontent.com/u/25754?v=4)](https://github.com/pmjones "pmjones (5 commits)")[![jdreesen](https://avatars.githubusercontent.com/u/424602?v=4)](https://github.com/jdreesen "jdreesen (1 commits)")[![schlessera](https://avatars.githubusercontent.com/u/83631?v=4)](https://github.com/schlessera "schlessera (1 commits)")

### Embed Badge

![Health badge](/badges/payload-interop-payload-interop/health.svg)

```
[![Health](https://phpackages.com/badges/payload-interop-payload-interop/health.svg)](https://phpackages.com/packages/payload-interop-payload-interop)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
