Search by

ExperienceBank PHP SDK

Package info

bitbucket.org/experiencebank/php-sdk

pkg:composer/experiencebank/php-sdk

Statistics

Installs: 71 278

Dependents: 0

Suggesters: 0

v2.0.0 2026-11-02 14:59 UTC

This package is auto-updated.

Last update: 2026-11-02 15:00:12 UTC


README

The ExperienceBank PHP SDK including an API client library

Installation

Requires PHP 8.3 or newer.

composer require experiencebank/php-sdk

Configuration

Simple client

<?php
use ExperienceBank\Sdk\ApiClient\Client;
use ExperienceBank\Sdk\ApiClient\Credentials;

$credentials = new Credentials(
    getenv('API_PUBLIC_KEY'),
    getenv('API_SECRET_KEY')
);

$apiClient = new Client($credentials);

Client with Redis cache and Monolog logging

Any PSR-16 cache can be used, for example symfony/cache:

<?php
use Symfony\Component\Cache\Adapter\RedisAdapter;
use Symfony\Component\Cache\Psr16Cache;
use Monolog\Handler\StreamHandler;
use Monolog\Logger;
use ExperienceBank\Sdk\ApiClient\Client;
use ExperienceBank\Sdk\ApiClient\Credentials;

$redis = new \Redis();
$redis->pconnect('127.0.0.1', 6379);

$cache = new Psr16Cache(new RedisAdapter($redis));

$credentials = new Credentials(
    getenv('API_PUBLIC_KEY'),
    getenv('API_SECRET_KEY')
);

$logger = new Logger('api-client');
$logger->pushHandler(new StreamHandler('api-client.log'));

$apiClient = Client::newCachingClient($credentials, $cache, $logger);

Only read methods are served from the cache (activity.find, availability.find, booking.get, category.find, marketplace.find, supplier.find, webhook.find). Methods which change something are always sent to the api, so a booking is never replayed from cache.

The default ttl is 30 seconds. Use withCache() to change it, or to add a cache to an existing client. A ttl of 0 caches without expiry, false disables caching. Without a cache of your own, an in-memory cache (ExperienceBank\Sdk\ApiClient\Cache\ArrayCache) is used:

$apiClient = $apiClient->withCache(60, $cache);

Client::isCacheable('booking.get');    // true
Client::isCacheable('booking.create'); // false

Upgrading to 2.0

2.0 requires PHP 8.3 or newer. Older PHP versions are supported by 1.x only.

doctrine/cache is abandoned and has been replaced by PSR-16 (psr/simple-cache 1, 2 or 3):

  • Client::newCachingClient(), Client::withCache() and CredentialsStorage::__construct() take a Psr\SimpleCache\CacheInterface instead of Doctrine\Common\Cache\Cache, and Client::getCache() returns one.
  • Replace Doctrine caches with a PSR-16 implementation, e.g. RedisCache with new Psr16Cache(new RedisAdapter($redis)) from symfony/cache, or ArrayCache with ExperienceBank\Sdk\ApiClient\Cache\ArrayCache.
  • Credentials stored through CredentialsStorage with a Doctrine cache can't be read through a PSR-16 cache, as both store their entries differently. Store them again after upgrading.
  • CredentialsStorage keys must be valid PSR-16 keys, so they can't contain any of {}()/\@:.

Usage

Creating a supplier

$response = $apiClient->supplier()->create([
    'name'=> 'Amazing Demo Activities',
    'partnerSupplierId' => '15873',
    'partner' => 'par_049a72c3-7a8d-48aa-94d1-0ba5a8e9e9f2',
    'contact' => [
        'name' => 'John Doe',
        'email' => 'another@example.com'
    ]
]);

$supplierId = $response->getValue('result.supplierId'); 

The following methods are currently supported:

$this->client->supplier()->create(array $params);
$this->client->supplier()->update(array $params);
$this->client->supplier()->enable($supplierId);
$this->client->supplier()->disable($supplierId);
$this->client->supplier()->delete($supplierId);
$this->client->supplier()->find(Query $query);
$this->client->supplier()->generateAutoLoginUrl($supplierId, $email)->forMapping($mappingId);
$this->client->activity()->updated(array $params);
$this->client->activity()->find(Query $query);
$this->client->availability()->updated(array $params);
$this->client->availability()->find(Query $query);
$this->client->booking()->create(CreateBookingRequest $request);
$this->client->booking()->commit(CommitBookingRequest $request);
$this->client->booking()->get(GetBookingRequest $request);
$this->client->booking()->cancel(CancelBookingRequest $request);
$this->client->booking()->cancelled($bookingId);
$this->client->ticket()->affected(array $params);
$this->client->mapping()->enable($supplierId, $marketplaceId, $partnerId);
$this->client->mapping()->disable($mappingId);
$this->client->marketplace()->find(Query $query = null);
$this->client->category()->find();
$this->client->webhook()->subscribe($event, $url);
$this->client->webhook()->unsubscribe($webhookId);
$this->client->webhook()->find(Query $query);




But you can also call other RPC methods using the request() method.

$this->client->request(string $method, array $params);

Webhooks

Subscribing

Subscribe an url to an event to get notified in real time. Only one webhook per event can exist, so point each event at its own url.

<?php
use ExperienceBank\Sdk\ApiClient\Methods\Webhook\Query;
use ExperienceBank\Sdk\ApiClient\Methods\Webhook\Event;

$response = $apiClient->webhook()->subscribe(
    Event::AVAILABILITY_UPDATED,
    'https://example.com/webhooks/availability-updated'
);

$webhookId = $response->getValue('result.webhookId');

// List the webhooks. Pass an empty Query to get all of them.
$response = $apiClient->webhook()->find(new Query());

foreach ($response->getValue('result.data') as $webhook) {
    echo $webhook['webhookId'].' '.$webhook['event'].' '.$webhook['url'];
}

// Paginate with the returned cursor
$next = $response->getValue('result.cursor.next');
if ($next !== null) {
    $response = $apiClient->webhook()->find((new Query())->withCursor($next));
}

$apiClient->webhook()->unsubscribe($webhookId);

The supported events are Event::ACTIVITY_UPDATED and Event::AVAILABILITY_UPDATED.

Receiving notifications

Your endpoint must reply with a 200 status within 2 seconds, otherwise the notification is considered failed. Failed notifications are not retried, so acknowledge first and do the work afterwards (e.g. on a queue).

The delivered payload does not contain the name of the event, so pass in the event that the receiving url is subscribed to:

<?php
use ExperienceBank\Sdk\ApiClient\Methods\Webhook\AvailabilityUpdated;
use ExperienceBank\Sdk\ApiClient\Methods\Webhook\Event;
use ExperienceBank\Sdk\ApiClient\Methods\Webhook\Notification;

// $body can be a raw json string, a decoded array or a PSR-7 stream
$notification = Notification::fromJson(Event::AVAILABILITY_UPDATED, $body);

if ($notification instanceof AvailabilityUpdated) {
    $notification->getSupplierId();
    $notification->getActivityId();
    $notification->getOptionId();
    $notification->getLocalDateTime();       // \DateTimeImmutable
    $notification->getLocalDateTimeString(); // raw ISO 8601 string
    $notification->getAvailableCapacity();
    $notification->getOldCapacity();

    foreach ($notification->getTicketCategories() as $ticketCategory) {
        $ticketCategory->getTicketCategoryId();
        $ticketCategory->getAvailableCapacity(); // int or null
    }
}

An ActivityUpdated notification carries getSupplierId() and getActivityId() only.

If you already know which event an endpoint receives you can skip the dispatch and call the concrete class directly:

$notification = AvailabilityUpdated::fromPayload($body);

Running tests

The tests need PHP 8.3 or newer and Composer. They don't call the real api, so no credentials or network access are needed.

Install the dependencies and run the whole suite:

composer install
vendor/bin/phpunit

Run a single test class, a single file or the tests matching a name:

vendor/bin/phpunit --filter ClientCacheTest
vendor/bin/phpunit tests/src/ApiClient/Cache/ArrayCacheTest.php
vendor/bin/phpunit --filter aTtlOfZeroCachesWithoutExpiry

The suite fails on any PHP deprecation, notice or warning triggered in src/, not only on failed assertions. Details are printed below the results.

Without a local PHP 8.3

Run Composer and PHPUnit through Docker instead:

docker run --rm --user "$(id -u):$(id -g)" -v "$PWD":/app -w /app composer:2 composer install
docker run --rm --user "$(id -u):$(id -g)" -v "$PWD":/app -w /app php:8.3-cli vendor/bin/phpunit

Replace php:8.3-cli with another tag, e.g. php:8.5-cli, to test against a newer PHP version.

Coding style and security checks

vendor/bin/php-cs-fixer check   # report coding style violations
vendor/bin/php-cs-fixer fix     # fix them
composer audit                  # check dependencies for known vulnerabilities

The coding style rules are configured in .php-cs-fixer.dist.php. composer audit needs Composer 2.4 or newer; with an older one, run it through the composer:2 Docker image as shown above.

Contributions

All contributions are welcomed through pull requests.

Please run the tests, the coding style fixer and composer audit (see Running tests) before submitting.

License

MIT. See LICENSE file.