SDK PHP para España
corp-merch/sdk en Packagist — PHP 8.1+, PSR-7/PSR-18, bridges nativos Laravel y Symfony, DTOs readonly.
Instalación e init
composer require corp-merch/sdk. $cm = new CorpMerch\Client(apiKey: getenv('CM_KEY'), country: 'ES'). Usa PSR-18 HTTP client — pasa cualquiera (Guzzle, Symfony HttpClient, default sensato). Aplica IVA 21% y FACe/SII (AEAT) para España; hub por defecto Madrid.
Quickstart — enviar pedido
$order = $cm->orders->create(idempotencyKey: Uuid::v4(), buyer: ['vat_id' => 'ES…'], lines: [['sku' => 'TSH-001', 'qty' => 200]], promisedDate: '2026-07-01'); echo $order->id; echo $order->estimatedIvaAmountCents. Devuelve DTO Order readonly. Errores lanzados como CorpMerch\Exception\ValidationException etc.
Bridges Laravel y Symfony
Laravel: instala corp-merch/sdk-laravel — registra singleton ligado a config('corp-merch.country'). Symfony: corp-merch/sdk-symfony añade un bundle con cliente autowired. Ambos paquetes incluyen middlewares webhook que validan firma y despachan eventos tipados en el event bus del framework.
FAQ
¿Versión mínima de PHP?
PHP 8.1 (readonly properties, enums). PHP 8.2 y 8.3 probados. PHP 7.x no soportado.
¿Qué HTTP client?
PSR-18 — bring your own. Descubrimiento por defecto vía http-interop/http-factory-discovery, detecta Guzzle o Symfony HttpClient.
¿Cómo se tipan las responses?
DTOs readonly (Order, Invoice, CatalogItem). Enums para estados (OrderStatus::ACCEPTED etc.). Strict types: declare(strict_types=1) en cada fichero.
¿Iteración de catálogo?
foreach ($cm->catalog->iterate(country: 'ES') as $item) { … } — basado en generators, fetch perezoso de páginas. Cancela con break sin desperdicio.
¿Código fuente?
MIT en GitHub: github.com/corp-merch/sdk-php. PSR-12 codestyle; PHPStan level 9 en CI.