SDK · compense/sdk
PHP
compense/sdk 1.1.0: installation with any PSR-18 client, configuration, Laravel and Symfony, errors, pagination, webhook verification and testing.
On this page
| Package | compense/sdk (namespace Compense\Sdk) |
| Version | 1.1.0 · API v1 |
| Requirements | PHP 8.1+ (declare(strict_types=1), readonly DTOs) |
| HTTP | Any PSR-18 client + PSR-17 factories, discovered with php-http/discovery (Guzzle suggested) |
| Repository | Appiasoft/compense-saas-sdk-php · guides in docs/ · examples in examples/ (plain PHP and Laravel) |
Install #
composer require compense/sdk guzzlehttp/guzzle
# or with Symfony HttpClient:
composer require compense/sdk symfony/http-client nyholm/psr7Client #
<?php
declare(strict_types=1);
use Compense\Sdk\CompenseClient;
use Compense\Sdk\RetryConfig;
$client = new CompenseClient(
apiKey: getenv('COMPENSE_API_KEY'), // cmp_...
environment: 'sandbox', // 'production' (default) | 'sandbox' | 'dev'; or baseUrl: '...'
timeout: 30.0, // applies when the SDK builds Guzzle
retry: new RetryConfig(maxAttempts: 3, retryWrites: false),
httpClient: null, // any PSR-18 (container, mocks…)
logger: $psrLogger, // PSR-3: deprecation warnings
);If you pass your own httpClient, set the timeout on it. The PSR-17 factories (requestFactory:,
streamFactory:) are discovered automatically if you don’t provide them.
Laravel #
Register a singleton in a service provider and receive it through injection:
// app/Providers/CompenseServiceProvider.php
$this->app->singleton(CompenseClient::class, static fn (): CompenseClient => new CompenseClient(
apiKey: (string) config('services.compense.key'),
environment: (string) config('services.compense.environment', 'sandbox'),
timeout: 30.0,
retry: new RetryConfig(maxAttempts: 3),
logger: Log::channel('stack'),
));
// In a controller:
public function store(Request $request, CompenseClient $compense) { /* ... */ }In Symfony, register CompenseClient as a service, passing it your
Psr\Http\Client\ClientInterface.
Conventions #
camelCasemethods with PHP 8 named arguments:$client->wallet->bills->pay(document: '1032456789', billerCode: 'EPM', reference: '123456789', amount: '90000').- Writes →
Compense\Sdk\Model\Transaction; reads → models (Balance,Resolution,Page,OffsetPage…) orarray. Every model keeps the body in->raw. - Administrative module: extra fields go as named arguments using the contract’s names
(
first_name: 'Ana',bank_account: '...'). - Decisions:
Compense\Sdk\Model\Decision::APPROVE/Decision::REJECT. Affiliates:new Compense\Sdk\Model\AffiliateRef('CC', '1032456789')or an array. - Amounts: decimal
int,stringorStringable;Money::normalize()produces the same text as Python.
Errors #
Namespace Compense\Sdk\Exception: CompenseException › CompenseConfigException,
TransportException (a PSR-18 failure, with the original in getPrevious()) and
CompenseApiException › AuthException, NotFoundException, IdempotencyConflictException,
ValidationException (errors()), RateLimitException (retryAfter), UpstreamException,
ServerException. Properties: status, title, detail, traceId, problem.
Pagination #
Page (hasNext()) and OffsetPage (hasMore, nextOffset) are iterable and countable; walk
through them with a do … while loop (Pagination).
Webhooks #
use Compense\Sdk\Webhook\Webhook;
use Compense\Sdk\Webhook\WebhookVerificationException;
$event = Webhook::verify(file_get_contents('php://input'), getallheaders(), [$newSecret, $oldSecret]);
// Laravel: Webhook::verify($request->getContent(), $request->headers->all(), $secrets)
// PSR-7: Webhook::verifyRequest($request, $secrets)
$event->eventId; $event->event(); $event->resource(); $event->isTest();A complete Laravel controller is in Verifying the signature.
Testing #
Inject any fake PSR-18 client (for example php-http/mock-client or your own
Psr\Http\Client\ClientInterface) into httpClient: and check the requests it receives. For
integration tests, use a sandbox key.
SDK development #
Everything runs in Docker: make test (PHPUnit on PHP 8.3), make test81 (PHP 8.1) and
make analyse (PHPStan at the maximum level).