2026-01-16 16:25:46 +03:00
2026-01-18 22:00:02 +03:00
2026-01-18 21:52:11 +03:00

Alfa Bank SDK (Unofficial)

Tests Static Analysis

Профессиональная PHP-библиотека для интеграции с API Альфа-Банка (BaaS и СБП). Построена на базе Saloon v3 и Spatie Laravel Data.

Требования

Установка

composer require apoloz/alfa-bank-sdk

Подготовка сертификатов (mTLS)

Взаимодействие с API Альфа-Банка требует двухстороннего TLS-соединения. Банк не выдает закрытый ключ, вы должны сгенерировать его самостоятельно.

1. Генерация закрытого ключа и запроса (CSR): Используйте OpenSSL для создания ключа и файла запроса. Создайте файл openssl.cnf:

[req]
distinguished_name = req_distinguished_name
prompt = no
[req_distinguished_name]
C = RU
L = Moscow
O = Название Вашей Компании
CN = ФИО Ответственного
emailAddress = your_email@company.com
1.2.643.100.4 = 1234567890 (Ваш ИНН)

Выполните команды в терминале:

# Генерация закрытого ключа (храните его в секрете!)
openssl genrsa -out private.key 2048

# Генерация запроса на сертификат
openssl req -new -key private.key -out request.csr -config openssl.cnf -utf8

2. Отправка в Банк: Отправьте файл request.csr на почту alfa_api@alfabank.ru. В ответ банк пришлет публичный сертификат (client.cer или client.crt).

3. Использование: Поместите полученный сертификат и ваш закрытый ключ в надежное место и укажите пути к ним в .env (переменные ALFA_BAAS_CERT_PATH и ALFA_BAAS_KEY_PATH).

Конфигурация (Laravel)

Опубликуйте файл конфигурации:

php artisan vendor:publish --tag=alfa-bank-config

Настройка .env

Добавьте следующие переменные в ваш файл .env. Вам понадобятся сертификаты (PEM) и ключи.

# --- BaaS (Номинальные счета, Выплаты) ---
ALFA_BAAS_ENVIRONMENT=sandbox # или production
ALFA_BAAS_CLIENT_ID=your-client-id
ALFA_BAAS_CLIENT_SECRET=your-client-secret
ALFA_BAAS_CERT_PATH=storage/certs/baas_cert.pem
ALFA_BAAS_KEY_PATH=storage/certs/baas_key.pem

# Опционально: Ключи для CMS-подписи (если отличаются от транспортных)
# ALFA_BAAS_SIGNING_CERT_PATH=storage/certs/sign_cert.pem
# ALFA_BAAS_SIGNING_KEY_PATH=storage/certs/sign_key.pem

# --- SBP (СБП, QR-коды) ---
ALFA_SBP_ENVIRONMENT=sandbox # или production
ALFA_SBP_ALIAS=your-key-name-alias
ALFA_SBP_CERT_PATH=storage/certs/sbp_cert.pem
ALFA_SBP_KEY_PATH=storage/certs/sbp_key.pem

# --- Webhooks ---
ALFA_WEBHOOK_USER=alfa
ALFA_WEBHOOK_PASSWORD=secret
# Для проверки JWS-подписи вебхуков (опционально)
ALFA_WEBHOOK_PUBLIC_KEY=storage/certs/alfa_public_key.pem

Файл конфигурации (config/alfa-bank.php)

Вот как выглядит структура конфигурационного файла по умолчанию. Вы можете использовать его для тонкой настройки, например, чтобы задать пути динамически.

return [
    'baas' => [
        'environment' => env('ALFA_BAAS_ENVIRONMENT', 'sandbox'),
        'client_id' => env('ALFA_BAAS_CLIENT_ID'),
        'client_secret' => env('ALFA_BAAS_CLIENT_SECRET'),
        'certificate_path' => env('ALFA_BAAS_CERT_PATH'),
        'private_key_path' => env('ALFA_BAAS_KEY_PATH'),
        // ...
    ],
    'sbp' => [
        'environment' => env('ALFA_SBP_ENVIRONMENT', 'sandbox'),
        'key_name_alias' => env('ALFA_SBP_ALIAS'),
        'certificate_path' => env('ALFA_SBP_CERT_PATH'),
        'private_key_path' => env('ALFA_SBP_KEY_PATH'),
        // ...
    ],
    'webhook' => [
        'user' => env('ALFA_WEBHOOK_USER'),
        'password' => env('ALFA_WEBHOOK_PASSWORD'),
        'alfa_public_key' => env('ALFA_WEBHOOK_PUBLIC_KEY'),
    ],
];

Подключение и Безопасность

SDK поддерживает две разные модели безопасности, используемые в API Альфа-Банка.

1. Подключение к СБП (Pay-in)

Шаги для получения доступа:

  1. Генерируете пару ключей: openssl req -x509 -newkey rsa:2048 -keyout client.key -out client.crt -nodes -days 3650.
  2. Отправляете client.crt менеджеру банка (acquiring@alfabank.ru).
  3. Получаете от банка alias (key-name) и TermNo.

Поток данных и подпись:

  • Transport: Обязательный MTLS. Вы должны передать client.crt и client.key в конфигурацию Guzzle/Saloon.
  • Payload: Тело запроса канонизируется по алгоритму JCS.
  • Signature: SHA256withRSA подпись JCS-строки помещается в заголовок Authorization.

SDK делает это автоматически:

// В config/alfa-bank.php
'sbp' => [
    'alias' => 'my-company-alias',
    'private_key' => storage_path('certs/client.key'),
    'cert' => storage_path('certs/client.crt'),
],

2. Подключение к BaaS (Номинальные счета)

Шаги для получения доступа:

  1. Регистрация в личном кабинете партнера.
  2. Получение client_id и client_secret для OAuth2.
  3. Регистрация публичного ключа для проверки подписей выплат.

Поток данных и подпись:

  • Auth: Стандартный OAuth2 Bearer Token.
  • Payload Signature: Для критических операций (выплаты, идентификация) требуется digestSignatures. Это массив CMS-подписей (PKCS7) в формате Base64, которыми подписываются финансовые поля.

Пример формирования CMS в SDK:

use Apoloz\AlfaBank\Utils\CmsSigner;

$payload = json_encode($dataToSign);
$signature = CmsSigner::sign($payload, $privateKey, $certificate);

// $signature помещается в массив digestSignatures

3. Авторизация Authorization Code Flow (H2H)

SDK использует нативный функционал Saloon для OAuth2.

1. Инициализация:

$baas = AlfaBank::baas(
    clientId: '...', clientSecret: '...', redirectUri: '...',
    certificatePath: '...', privateKeyPath: '...'
);

2. Получение ссылки на вход:

$url = $baas->getAuthorizationUrl(['beneficiaries']);
// Перенаправьте пользователя на $url

3. Обмен кода на токен:

$authenticator = $baas->getAccessToken($code);
$baas->authenticate($authenticator); // Применить токен
// Сохраните $authenticator->getRefreshToken() в БД

4. Обновление токена:

$newAuth = $baas->refreshAccessToken($savedRefreshToken);
$baas->authenticate($newAuth);

Полный пример: examples/13_h2h_auth_service.php

4. Генерация Client Secret (Утилита)

Если банк выдал только сертификаты, вы можете сгенерировать client_secret самостоятельно:

// См. examples/14_generate_client_secret.php
$baas->send(new RefreshClientSecretRequest($clientId));

Важно для продакшена: Запрос нового секрета инвалидирует старый. Если у вас запущено несколько экземпляров приложения (или worker-ов), не запрашивайте секрет при каждом старте. Решение: Получите секрет один раз, сохраните в общий кеш (Redis/DB) с TTL (например, 29 дней) и запрашивайте новый только при истечении срока или отсутствии в кеше. Полный пример автоматизации: examples/16_automated_startup.php


Архитектура и Потоки данных

Гибридный поток: СБП -> Номинальный счет

sequenceDiagram
    participant Client as Покупатель
    participant SBP as SDK (SBP Connector)
    participant API as Alfa Bank API
    participant BaaS as SDK (BaaS Connector)

    Note over SBP, API: MTLS + JCS Signature
    SBP->>API: 1. GetQrCodeRequest(NominalAcc)
    API-->>SBP: 2. QR Payload (URL)
    Client->>API: 3. Оплата в приложении (СБП)

    Note over API, BaaS: Webhook with Signature
    API->>BaaS: 4. Webhook (Входящий платеж)
    
    Note over BaaS, API: OAuth2 + CMS Signature
    BaaS->>API: 5. IdentifyTransactionRequest(beneficiaryId)
    API-->>BaaS: 6. 200 OK (Зачислено)

Примеры использования

1. СБП: Прием платежа на номинальный счет

use Apoloz\AlfaBank\Laravel\Facades\Sbp;
use Apoloz\AlfaBank\Sbp\Requests\GetQrCodeRequest;
use Apoloz\AlfaBank\Sbp\Data\QrCodeRequestData;

$response = Sbp::send(new GetQrCodeRequest(
    new QrCodeRequestData(
        termNo: '90080567',
        amount: '10000', // 100.00 RUB
        paymentPurpose: 'Пополнение кошелька #123'
    )
));

echo "QR URL: " . $response->dto()->payload;

2. Идентификация платежа (BaaS)

Когда платеж пришел на номинальный счет, его нужно привязать к бенефициару:

use Apoloz\AlfaBank\Requests\NominalAccounts\Identification\IdentifyTransactionRequest;
use Apoloz\AlfaBank\Data\NominalAccounts\Identification\IdentifyRequestData;
use Apoloz\AlfaBank\Data\NominalAccounts\Identification\AmountDistributionData;

$data = new IdentifyRequestData(
    transactionId: '1220112MOCO#DS4001415',
    accountNumber: '40702810...',
    amountDistribution: AmountDistributionData::collect([
        ['beneficiaryId' => 'BEN-001', 'amount' => '100.00']
    ], DataCollection::class),
    digestSignatures: ... // CMS подпись
);

AlfaBank::send(new IdentifyTransactionRequest($data));

3. Работа с номинальными счетами (Бенефициары)

... (existing content) ...

4. Самозанятые (Регистрация доходов)

use Apoloz\AlfaBank\Requests\SelfEmployed\RegisterIncomeRequest;
use Apoloz\AlfaBank\Data\SelfEmployed\CreateIncomeRequestData;

$data = new CreateIncomeRequestData(
    vatin: '1234567890',
    name: 'Консультационные услуги',
    amount: '5000.00',
    date: now()->format('Y-m-d')
);

$response = AlfaBank::send(new RegisterIncomeRequest($data));

5. Файловый обмен (KYC)

Загрузка сканов документов бенефициаров через pre-signed ссылки:

use Apoloz\AlfaBank\Requests\Files\UploadFileRequest;

$file = fopen('document.pdf', 'r');
$uploadUrl = 'https://baas.alfabank.ru/filebox/...'; // Получено из метода создания бенефициара

AlfaBank::send(new UploadFileRequest($uploadUrl, $file));

Продвинутые возможности

Управление возвратами СБП

Просмотр всей истории попыток возврата по транзакции:

$response = Sbp::send(new GetQrcReversalHistoryRequest($payrrn, $termNo));
foreach ($response->dto()->refunds as $refund) {
    echo "Статус возврата: " . $refund->status;
}

Webhook Handling (Laravel)

// Обработка СБП уведомлений в Listener
public function handle(AlfaWebhookReceived $event) {
    if ($event->webhook->isSbp()) {
        $data = Sbp::parsePaymentNotification($event->webhook->payload);
        Log::info("СБП Оплата: {$data->amount} коп.");
    }
}

Лицензия

MIT. Автор: Anatoliy Poloz.

Description
No description provided
Readme MIT 6.5 MiB
Languages
PHP 100%