iabduul7/laravel-themepark-booking-adapters
Composer 安装命令:
composer require iabduul7/laravel-themepark-booking-adapters
包简介
Self-contained, drop-in Laravel booking adapters for Walt Disney World & SeaWorld/United Parks (Redeam) and Universal Orlando (SmartOrder): catalog, pricing, availability, holds/bookings, orders and voucher data.
README 文档
README
A Laravel package providing self-contained, drop-in booking adapters for major theme park distribution APIs:
| Park | Provider | Adapter |
|---|---|---|
| Walt Disney World | Redeam | DisneyRedeamAdapter |
| SeaWorld / United Parks | Redeam | SeaWorldRedeamAdapter |
| Universal Orlando | SmartOrder ("SmartOrder2") | UniversalSmartOrder2Adapter |
Each adapter exposes the provider's real API surface (catalog, rates, availability, pricing schedules, holds/bookings for Redeam; events/orders for SmartOrder) and returns lightweight DTOs over the raw responses. Auth, retries and OAuth token management are handled for you.
What's working today: all three adapters are contract-tested with
Http::fakeand analysed with PHPStan (level 3). Read paths (catalog, rates, pricing, availability) are additionally verified against the live provider sandboxes, and the full write lifecycle is proven live for Disney (Redeam hold → book → cancel) and Universal (SmartOrder place → cancel). SeaWorld / United Parks is contract-tested only — its sandbox (Discovery Cove) exposes no bookable availability.
Features
- Three production parks supported: Disney (Redeam), SeaWorld/United Parks (Redeam), Universal (SmartOrder)
- Driver-based resolution via a Laravel
Manager+ThemeParkfacade - Auth handled: Redeam
X-API-Key/X-API-Secret; SmartOrder OAuth2 client-credentials with token caching and 401 self-heal - Resilient transport: idempotent reads retried on connection drops / 5xx; writes never retried (no double-booking)
- Typed result objects:
Supplier,Product,Rate,PriceSchedule,RatePriceSchedule,Availability,Hold,Booking, … - Voucher data exposed:
tickets()normalises each booking/order response into typedTicketArtifacts (redeemable identifier + format + validity); barcode/PDF rendering stays in your app - Capability interfaces:
SupportsHolds,SupportsEvents,ProvidesTicketArtifacts— type-hint a capability instead of a concrete park - No app coupling: pure API integration; persistence, jobs, commission/margins and voucher rendering stay in your app
- Contract-tested with
Http::fake(), analysed with PHPStan, and exercised live against the provider sandboxes
Requirements
- PHP 8.2, 8.3 or 8.4
- Laravel 12.x or 13.x (
illuminate/contracts ^12.0|^13.0)
Earlier releases targeted PHP 8.1 / Laravel 10–11. Support for those was dropped in 3.0.0 to stay on the security-patched Laravel line (≥ 12.60 / ≥ 13.10); see the changelog.
Installation
composer require iabduul7/laravel-themepark-booking-adapters
Publish the config file:
php artisan vendor:publish --tag="themepark-adapters-config"
Add credentials to your .env (see .env.example for the full list):
THEMEPARK_DEFAULT_PROVIDER=disney # Disney (Redeam) REDEAM_DISNEY_SUPPLIER_ID=your_disney_supplier_id REDEAM_DISNEY_API_KEY=your_disney_api_key REDEAM_DISNEY_API_SECRET=your_disney_api_secret # SeaWorld / United Parks (Redeam) — supplier is passed per call REDEAM_UNITED_PARKS_API_KEY=your_seaworld_api_key REDEAM_UNITED_PARKS_API_SECRET=your_seaworld_api_secret # Universal (SmartOrder) SMARTORDER_CUSTOMER_ID=134853 SMARTORDER_APPROVED_SUFFIX=-2KNOW SMARTORDER_CLIENT_USERNAME=your_client_username SMARTORDER_CLIENT_SECRET=your_client_secret
Usage
Resolving an adapter
use Iabduul7\ThemeParkAdapters\Facades\ThemePark; $disney = ThemePark::provider('disney'); // DisneyRedeamAdapter $seaworld = ThemePark::provider('seaworld'); // SeaWorldRedeamAdapter $universal = ThemePark::provider('universal'); // UniversalSmartOrder2Adapter
You can also resolve via the container (app('themepark') / ThemeParkManager) or construct an
adapter directly with a config array:
use Iabduul7\ThemeParkAdapters\Providers\Disney\DisneyRedeamAdapter; $disney = new DisneyRedeamAdapter(config('themepark-adapters.providers.disney'));
Disney (Redeam) — supplier fixed from config
$products = $disney->getAllProducts(); // Product[] $product = $disney->getProduct('PRODUCT_ID'); // Product $rates = $disney->getProductRates('PRODUCT_ID'); // Rate[] $schedule = $disney->getProductPricingSchedule('PRODUCT_ID', '2026-06-01', '2026-06-30'); // PriceSchedule $rateSched = $disney->getProductRatePricingSchedule('PRODUCT_ID', '2026-06-01', '2026-06-30', 'RATE_ID'); $avail = $disney->checkAvailabilities('PRODUCT_ID', '2026-06-01', '2026-06-30'); // Hold → book → cancel $hold = $disney->createNewHold(['hold' => ['items' => [/* … */]]]); $booking = $disney->createNewBooking(['booking' => [/* … */]]); $disney->deleteBooking('BOOKING_ID'); echo $product->getName(); echo $product->getId();
SeaWorld / United Parks (Redeam) — supplier passed per call
$products = $seaworld->getAllProducts('SUPPLIER_ID'); $product = $seaworld->getProduct('SUPPLIER_ID', 'PRODUCT_ID'); $rates = $seaworld->getProductRates('SUPPLIER_ID', 'PRODUCT_ID'); $schedule = $seaworld->getProductPricingSchedule('SUPPLIER_ID', 'PRODUCT_ID', '2026-06-01', '2026-06-30');
Universal (SmartOrder)
$catalog = $universal->getAllProducts(); // GET smartorder/MyProductCatalog $months = $universal->getAvailableMonths(); // next 12 months $events = $universal->findEvents([/* plu, dates, … */]); // POST smartorder/FindEvents $order = $universal->placeOrder([/* order lines, … */]);// POST smartorder/PlaceOrder if ($universal->canCancelOrder(['ExternalOrderId' => 'E1'])) { $universal->cancelOrder(['ExternalOrderId' => 'E1']); }
The adapters mirror the method names and signatures of the production
LaravelRedeamForWaltDisney,LaravelRedeamForUnitedParksandSmartOrderClientclients so they can serve as a drop-in replacement. A normalised, provider-agnostic interface is proposed for a future major version.
Capability interfaces
Contracts\Capabilities\SupportsHolds—createNewHold,getHold,deleteHold,createNewBooking,getBooking,deleteBooking(Redeam adapters)Contracts\Capabilities\SupportsEvents—findEvents,placeOrder,getExistingOrder,canCancelOrder,cancelOrder(SmartOrder adapter)
Type-hint these when you only need a capability rather than a specific park.
Optional building blocks
Business logic that is specific to a deployment is kept out of the core adapters and shipped as
opt-in helpers under Support/:
Support\Redeam\OptionCodeResolver— maps a Walt Disney World ticket name to its Redeam option code (also exposed on the Redeam adapters asgetOptionCode()for drop-in parity).
Persistence (Eloquent models, migrations), queue/sync jobs, commission/operator margins and voucher rendering (barcode images,
templates, PDF, delivery) are intentionally left to the consuming application. The package does expose
the provider-native voucher data — tickets() normalises each booking/order response into typed
TicketArtifacts (the redeemable identifier + format + validity).
Authentication
- Redeam —
X-API-Key/X-API-Secretheaders; GET is form-encoded, writes are JSON. - SmartOrder — OAuth2 client-credentials (
/connect/token,scope=SmartOrder); bearer token cached via aTokenRepository(setSMARTORDER_TOKEN_CACHE=falseto always refresh, matching upstream);customerIdinjected into every request; transparent refresh-and-retry on401.
Error handling
Any non-2xx provider response is raised as a ThemeParkApiException — reads and writes alike (a
failure is never silently returned as an empty array). The exception carries the HTTP status via
getCode() and the decoded provider error body via getResponseData(). Single-entity lookups raise
a dedicated 404: getProduct() throws productNotFound(), getExistingOrder() throws
orderNotFound().
One deliberate exception: deleteBooking() (the Redeam booking cancel) returns the raw
Illuminate\Http\Client\Response instead of throwing, since Redeam replies 204 with no body. This
keeps drop-in parity with the upstream client — callers check ->status() themselves rather than
catching an exception.
use Iabduul7\ThemeParkAdapters\Exceptions\ThemeParkApiException; try { $product = ThemePark::provider('disney')->getProduct('PRODUCT_ID'); } catch (ThemeParkApiException $e) { $status = $e->getCode(); // e.g. 404, 422, 503 $body = $e->getResponseData(); // decoded provider error payload (nullable) report($e); }
Idempotent reads are retried on connection drops / 5xx before the failure surfaces; writes are never retried (no double-booking).
Development
composer install
Testing
# Adapter contract tests (Http::fake) composer test:adapters # Static analysis composer analyse # Code style composer format # fix composer format:check # check only
Changelog
Please see CHANGELOG for more information on what has changed recently.
Contributing
Please see CONTRIBUTING for details.
Credits
License
The MIT License (MIT). Please see License File for more information.
iabduul7/laravel-themepark-booking-adapters 适用场景与选型建议
iabduul7/laravel-themepark-booking-adapters 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 4 次下载、GitHub Stars 达 0, 最近一次更新时间为 2025 年 12 月 02 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「laravel」 「tickets」 「adapters」 「booking」 「iabduul7」 「theme-park」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 iabduul7/laravel-themepark-booking-adapters 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 iabduul7/laravel-themepark-booking-adapters 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 iabduul7/laravel-themepark-booking-adapters 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
iOS Passbook for Symfony
OhCache is a flexible caching library for PHP
Yii2 utils provides various utility classes and helpers that are compatible with the Yii2 framework
An embeddable support ticket system for Laravel applications
SQL Repository implementation
Laravel wrapper for PHP YouTrack SDK.
统计信息
- 总下载量: 4
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 28
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2025-12-02