PHP code example of vs-point / kb-adaa

1. Go to this page and download the library: Download vs-point/kb-adaa library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

vs-point / kb-adaa example snippets


use VsPoint\KbAdaa\Config\KbAdaaConfig;            // pro runtime ADAA volání
use VsPoint\KbAdaa\Config\OAuth2Config;            // pro token endpoint
use VsPoint\KbAdaa\Config\ClientRegistrationConfig; // pro software statement (mTLS)

use VsPoint\KbAdaa\Enum\Environment;

Environment::Sandbox     // https://api-gateway.kb.cz/sandbox/...
Environment::Production  // https://api-gateway.kb.cz/... (Client Registration má vlastní host)

interface TokenStorageInterface {
    public function load(): ?AccessToken;
    public function save(AccessToken $token): void;
    public function clear(): void;
}

use VsPoint\KbAdaa\Config\KbAdaaConfig;
use VsPoint\KbAdaa\Config\OAuth2Config;
use VsPoint\KbAdaa\Enum\Environment;
use VsPoint\KbAdaa\KbAdaaClient;
use VsPoint\KbAdaa\Token\AccessToken;
use VsPoint\KbAdaa\Token\InMemoryTokenStorage;

$tokenStorage = new InMemoryTokenStorage(new AccessToken(
    accessToken: 'eyJ...',
    refreshToken: 'eyJ...',
    expiresAt: time() + 180,
    scope: 'adaa',
));

$client = KbAdaaClient::create(
    config: new KbAdaaConfig(
        apiKey: 'adaa-api-key',
        environment: Environment::Production,
    ),
    tokenStorage: $tokenStorage,
    // Volitelné — povoluje auto-refresh tokenu:
    oauth2Config: new OAuth2Config(
        apiKey: 'oauth2-api-key',
        clientId: 'YourApp-1234',
        clientSecret: 'shh',
        redirectUri: 'https://nas-produkt.cz/kb/callback',  // KB ho vyžaduje i u refresh
        environment: Environment::Production,
    ),
);

// Účty
foreach ($client->accounts->list() as $account) {
    echo $account->iban . ' (' . $account->currency?->getCurrencyCode() . ')' . PHP_EOL;
}

use VsPoint\KbAdaa\Config\ClientRegistrationP12Config;

$config = ClientRegistrationP12Config::fromFile(
    apiKey: 'cr-api-key',
    p12Path: '/secrets/qualified-cert.p12',
    p12Password: 'heslo-k-p12',
    environment: Environment::Production,
);

$config = new ClientRegistrationP12Config(
    apiKey: 'cr-api-key',
    p12Content: $secretManager->get('kb-qualified-cert.p12'),
    p12Password: $secretManager->get('kb-qualified-cert-password'),
    environment: Environment::Production,
);

use VsPoint\KbAdaa\Config\ClientRegistrationConfig;

$config = new ClientRegistrationConfig(
    apiKey: 'cr-api-key',
    certPath: '/secrets/qualified-cert.pem',
    certPassword: null,           // pokud je PEM zašifrovaný
    keyPath: null,                // pokud je klíč v jiném souboru
    keyPassword: null,
    environment: Environment::Production,
);

use VsPoint\KbAdaa\Config\ClientRegistrationInlineConfig;

$config = new ClientRegistrationInlineConfig(
    apiKey: 'cr-api-key',
    certPem: $_ENV['KB_QUALIFIED_CERT_PEM'],
    keyPem: $_ENV['KB_QUALIFIED_KEY_PEM'],   // pokud klíč není v certPem
    environment: Environment::Production,
);

use VsPoint\KbAdaa\DTO\ClientRegistration\SoftwareStatementPayload;

$statement = $client->clientRegistration->issue(new SoftwareStatementPayload(
    softwareName: 'Náš produkt',
    softwareNameEn: 'Our product',
    softwareId: bin2hex(random_bytes(16)),
    softwareVersion: '1.0',
    softwareUri: 'https://nas-produkt.cz',
    redirectUris: ['https://nas-produkt.cz/kb/callback'],
    registrationBackUri: 'https://nas-produkt.cz/kb/registration-back',
    contacts: ['email: [email protected]'],
));

echo $statement->token;                     // raw JWT
echo $statement->claims->vendorName;        // dekódované claims
echo $statement->claims->exp;               // expirace (12 měsíců)
// → ulož $statement->token do secret manageru, použiješ při registraci aplikace

use VsPoint\KbAdaa\DTO\ApplicationRegistration\RegistrationRequest;
use VsPoint\KbAdaa\Enum\ApplicationType;
use VsPoint\KbAdaa\Enum\Scope;

// Vygeneruj a ulož AES-256 klíč — budeš ho potřebovat pro dešifrování callbacku.
$encryptionKey = $client->applicationRegistration->generateEncryptionKey();
// $encryptionKey ulož do session / DB svázaný s registrací

$redirectUrl = $client->applicationRegistration->buildRedirectUrl(
    Environment::Production,
    new RegistrationRequest(
        clientName: 'Náš produkt',
        clientNameEn: 'Our product',
        redirectUris: ['https://nas-produkt.cz/kb/callback'],
        scope: [Scope::Adaa, Scope::CardData],
        encryptionKey: $encryptionKey,
        softwareStatement: $statement->token,
        applicationType: ApplicationType::Web,
    ),
);

// Redirectni uživatele
header('Location: ' . $redirectUrl);

$registration = $client->applicationRegistration->decryptResponse(
    base64Salt: $_GET['salt'],
    base64EncryptedData: $_GET['encryptedData'],
    base64EncryptionKey: $encryptionKey,    // tentýž klíč jako výše
);

echo $registration->clientId;       // ulož do DB
echo $registration->clientSecret;   // ulož do DB

$loginUrl = $client->oauth2->buildAuthorizationUrl(
    scopes: [Scope::Adaa],
    state: bin2hex(random_bytes(16)),
);

header('Location: ' . $loginUrl);

$accessToken = $client->oauth2->exchangeAuthorizationCodeForToken(code: $_GET['code']);

$tokenStorage->save($accessToken);

$accounts = $client->accounts->list();

foreach ($accounts as $account) {
    echo $account->accountId . ' — ' . $account->iban . PHP_EOL;
}

// accountId se nemění — cachuj ho, ať nepáliš zbytečně API call

foreach ($client->balances->list($accountId) as $balance) {
    echo $balance->type?->value . ': ' . $balance->amount?->toMoney() . PHP_EOL;
}
// CLOSING_AVAILABLE: CZK 85,061.41
// PREVIOUSLY_CLOSED_BOOK: CZK 85,061.41

use Brick\DateTime\Duration;
use Brick\DateTime\TimeZone;
use Brick\DateTime\ZonedDateTime;
use VsPoint\KbAdaa\DTO\Transaction\TransactionQuery;

$now = ZonedDateTime::now(TimeZone::utc());

$page = $client->transactions->list(
    $accountId,
    new TransactionQuery(
        fromDateTime: $now->minusDuration(Duration::ofDays(30)),
        toDateTime: $now,
        page: 0,
        size: 100,    // max 100 (KB-enforced)
    ),
);

foreach ($page->content as $tx) {
    echo $tx->bookingDate . ' ' . $tx->amount?->toMoney() . ' ' . $tx->status?->value . PHP_EOL;

    // Pro párování PDNG → BOOK použij references.accountServicer
    echo '  pair key: ' . $tx->references?->accountServicer . PHP_EOL;
}

use Brick\DateTime\ZonedDateTime;
use VsPoint\KbAdaa\DTO\Statement\StatementListQuery;

$statements = $client->statements->list(
    $accountId,
    new StatementListQuery(dateFrom: ZonedDateTime::parse('2024-01-01T00:00:00Z')),
);

foreach ($statements as $statement) {
    $pdf = $client->statements->download($accountId, $statement->statementId);
    file_put_contents("statement-{$statement->statementId}.pdf", $pdf);
}

use VsPoint\KbAdaa\DTO\EventSubscription\CreateSubscriptionPayload;

$subscription = $client->eventSubscriptions->create(
    $accountId,
    new CreateSubscriptionPayload(
        eventApiUrl: 'https://nas-produkt.cz/webhook/kb-events',
        eventApiKey: bin2hex(random_bytes(32)),    // sdílené tajemství — KB ho posílá jako x-api-key header
    ),
);

echo $subscription->subscriptionId;   // ulož do DB ke svému účtu

// Později:
$client->eventSubscriptions->delete($accountId, $subscription->subscriptionId);

// V tvém controlleru pro POST /subscriptions/{subscriptionId}/events
try {
    $payload = $client->eventApi->handleEvent(
        jsonBody: file_get_contents('php://input'),
        expectedApiKey: $mySubscriptionApiKey,         // ten, co jsi předal při create()
        providedApiKey: $request->headers->get('x-api-key', ''),
    );

    // $payload->eventCount — počet nových událostí
    // Spusť fetch nových transakcí (async, neblokuj odpověď)
    dispatch_to_queue(new FetchKbTransactions($accountId));

    http_response_code(204);
} catch (InvalidEventApiKeyException) {
    http_response_code(401);
    echo $client->eventApi->errorResponseJson('Invalid API key');
}

// V controlleru pro GET /version
header('Content-Type: application/json');
echo $client->eventApi->versionResponseJson();

use VsPoint\KbAdaa\Exception\KbAdaaApiException;
use VsPoint\KbAdaa\Exception\NotFoundException;
use VsPoint\KbAdaa\Exception\RateLimitException;

try {
    $balances = $client->balances->list($accountId);
} catch (NotFoundException $e) {
    // accountId neexistuje
} catch (RateLimitException $e) {
    sleep($e->getRetryAfterSeconds() ?? 60);
} catch (KbAdaaApiException $e) {
    error_log($e->getHttpStatus() . ': ' . $e->getErrorCode() . ' — ' . $e->getResponseBody());
}

use VsPoint\KbAdaa\Enum\Scope;
use VsPoint\KbAdaa\Sandbox\SandboxAuthorizationCodeFactory;

$code = (new SandboxAuthorizationCodeFactory())->generate(
    userId: 'test',                       // libovolný neprázdný string — sandbox nehlídá
    scopes: [Scope::Adaa, Scope::CardData],
);

$token = $client->oauth2->exchangeAuthorizationCodeForToken(code: $code);

$tokenStorage->save($token);
// Hotovo — můžeš volat $client->accounts->list() atd.