koh / sylius-mpp
MPP payment discovery for Sylius: an OpenAPI document at /openapi.json carrying x-payment-info on payable operations.
Requires
- php: ^8.3
- koh/sylius-agent-contracts: ^1.1
- sylius/sylius: ^2.2.9 || ^2.3.0
- symfony/config: ^7.4 || ^8.0
- symfony/dependency-injection: ^7.4 || ^8.0
- symfony/http-foundation: ^7.4 || ^8.0
- symfony/http-kernel: ^7.4 || ^8.0
- symfony/routing: ^7.4 || ^8.0
Requires (Dev)
- koh/dev-sylius: ^1.0
- phpstan/extension-installer: ^1.4.3
- phpstan/phpstan: ^2.3.1
- phpstan/phpstan-doctrine: ^2.0.28
- phpunit/phpunit: ^11.5.57
Suggests
None
Provides
None
Conflicts
None
Replaces
None
- v1.1.37
- v1.1.36
- v1.1.35
- v1.1.34
- v1.1.33
- v1.1.32
- v1.1.31
- v1.1.30
- v1.1.29
- v1.1.28
- v1.1.27
- v1.1.26
- v1.1.25
- v1.1.24
- v1.1.23
- v1.1.22
- v1.1.21
- v1.1.20
- v1.1.19
- v1.1.18
- v1.1.17
- v1.1.16
- v1.1.15
- v1.1.14
- v1.1.13
- v1.1.12
- v1.1.11
- v1.1.10
- v1.1.9
- v1.1.8
- v1.1.7
- v1.1.6
- v1.1.5
- v1.1.4
- v1.1.3
- v1.1.2
- v1.1.1
- v1.1.0
- dev-main / 1.0.x-dev
- v1.0.0
This package is auto-updated.
Last update: 2026-10-18 11:47:39 UTC
README
koh/sylius-mpp
MPP payment discovery for Sylius: an OpenAPI 3.1 document at /openapi.json
that lists the shop's agent endpoints and marks the payable ones with
x-payment-info.
- One document for agents — every endpoint the other
kohbundles register (ACP feed, MCP, llms.txt, …) appears as a path, without listing them by hand. - Prices from the same source as enforcement — payable operations come from
PayableOperationProviderInterface, whichkoh/sylius-x402also reads to charge. A route cannot advertise a price it does not charge. - Conflicts fail loudly — two providers pricing the same operation differently raise an error instead of publishing whichever was wired last.
- Independent of API Platform — API Platform keeps its own document at
/docs.jsonopenapi; this one answers at/openapi.json, where MPP discovery looks.
Requires PHP 8.3 or later and Sylius 2.2 or 2.3.
Install
composer require koh/sylius-mpp
Register the bundle and the shared contracts bundle it builds on:
// config/bundles.php return [ // … Koh\SyliusAgentContracts\KohSyliusAgentContractsBundle::class => ['all' => true], Koh\SyliusMpp\KohSyliusMppBundle::class => ['all' => true], ];
Import the route:
# config/routes/koh_agent.yaml koh_mpp: resource: '@KohSyliusMppBundle/config/routes.php'
Clear the cache and check the document:
bin/console cache:clear curl -s https://shop.example.com/openapi.json
If public/openapi.json exists, delete it: the web server answers from disk
before Symfony is asked.
Configure
One optional setting, the service categories announced in x-service-info:
# config/packages/koh_mpp.yaml koh_mpp: categories: ['data', 'search']
Declaring a payable operation
Install koh/sylius-x402 and configure its price table — this bundle picks the
prices up from there. Or implement the contract yourself and tag the service
koh_agent.payable_operation:
use Koh\SyliusAgentContracts\Context\AgentContext; use Koh\SyliusAgentContracts\Model\PayableOperation; use Koh\SyliusAgentContracts\Provider\PayableOperationProviderInterface; final class FeedPrice implements PayableOperationProviderInterface { public function getPayableOperations(AgentContext $context): iterable { yield new PayableOperation( path: '/api/agent/feed', method: 'GET', intent: 'charge', payMethod: 'x402', amount: '10000', // smallest unit of the currency currency: '0x…', // ISO 4217 for fiat, contract address for a token description: 'Product feed', ); } }
Output
GET /openapi.json with the ACP feed installed and priced:
{
"openapi": "3.1.0",
"info": { "title": "Fashion Web Store — agent API", "version": "1.0.0" },
"servers": [{ "url": "https://shop.example.com" }],
"x-service-info": {
"categories": ["data", "search"],
"docs": {
"homepage": "https://shop.example.com",
"llms": "https://shop.example.com/llms.txt"
}
},
"paths": {
"/.well-known/acp.json": {
"get": {
"summary": "ACP discovery",
"description": "Agentic Commerce Protocol: catalogue access for agents.",
"responses": { "200": { "description": "Success" } }
}
},
"/api/agent/feed": {
"get": {
"summary": "Product feed",
"description": "Paginated, SKU-level product feed.",
"responses": {
"200": { "description": "Success" },
"402": { "description": "Payment Required" }
},
"x-payment-info": {
"intent": "charge",
"method": "x402",
"amount": "10000",
"currency": "0x…",
"description": "Product feed"
}
}
}
}
}
Every payable operation also gets a 402 response, so a client can plan for
payment instead of treating it as an error. The document is registered in
/.well-known/api-catalog as the origin's service description.
Decommission
Remove the composer require, the config/bundles.php entry, the route import
and config/packages/koh_mpp.yaml. No database table, no cache pool.
Security
Report vulnerabilities privately — see SECURITY.md. Advisories are published as CSAF 2.0 at https://ole-hartwig.eu/.well-known/csaf/.
The family threat model, covering this package, is at https://github.com/ohartwig/sylius-agent-ready/blob/main/docs/threat-model.md.
Licence
MIT — see LICENSE.