doc(update)

This commit is contained in:
2026-01-19 00:22:30 +03:00
parent a8f84de46f
commit 901a94b59a

263
README.md
View File

@@ -8,210 +8,163 @@
## Требования
- PHP 8.2+
- Расширение OpenSSL
- [Saloon](https://docs.saloon.dev) v3.0+
- [Spatie Laravel Data](https://spatie.be/docs/laravel-data)
## Установка
## Подключение и Безопасность
```bash
composer require apoloz/alfa-bank-sdk
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 делает это автоматически**:
```php
// В config/alfa-bank.php
'sbp' => [
'alias' => 'my-company-alias',
'private_key' => storage_path('certs/client.key'),
'cert' => storage_path('certs/client.crt'),
],
```
---
## Архитектура и потоки данных
### 2. Подключение к BaaS (Номинальные счета)
Библиотека обеспечивает строгую типизацию на всех этапах. Вы работаете только с объектами (DTO), а SDK берет на себя всю сложность протоколов банка.
**Шаги для получения доступа:**
1. Регистрация в личном кабинете партнера.
2. Получение `client_id` и `client_secret` для OAuth2.
3. Регистрация публичного ключа для проверки подписей выплат.
### 1. Жизненный цикл запроса (BaaS)
**Поток данных и подпись:**
* **Auth**: Стандартный OAuth2 Bearer Token.
* **Payload Signature**: Для критических операций (выплаты, идентификация) требуется `digestSignatures`. Это массив CMS-подписей (PKCS7) в формате Base64, которыми подписываются финансовые поля.
**Пример формирования CMS в SDK:**
```php
use Apoloz\AlfaBank\Utils\CmsSigner;
$payload = json_encode($dataToSign);
$signature = CmsSigner::sign($payload, $privateKey, $certificate);
// $signature помещается в массив digestSignatures
```
---
## Архитектура и Потоки данных
### Гибридный поток: СБП -> Номинальный счет
```mermaid
sequenceDiagram
participant App as Приложение
participant DTO as Request DTO
participant SDK as Connector
participant API as Alfa Bank
participant Client as Покупатель
participant SBP as SDK (SBP Connector)
participant API as Alfa Bank API
participant BaaS as SDK (BaaS Connector)
App->>DTO: 1. Создание данных
App->>SDK: 2. send(Request)
SDK->>SDK: 3. Маппинг полей (PascalCase)
SDK->>SDK: 4. Подпись/Шифрование
SDK->>API: 5. HTTPS + mTLS
API-->>SDK: 6. JSON Ответ
SDK->>SDK: 7. Валидация ошибок
SDK->>App: 8. Возврат Response DTO
```
Note over SBP, API: MTLS + JCS Signature
SBP->>API: 1. GetQrCodeRequest(NominalAcc)
API-->>SBP: 2. QR Payload (URL)
Client->>API: 3. Оплата в приложении (СБП)
### 2. Безопасность СБП (Body Signing)
Для СБП реализована автоматическая каноникализация JSON (JCS) с рекурсивной сортировкой ключей перед подписью RSA-SHA256.
---
## Настройка и Безопасность
Альфа-Банк требует **два набора ключей**:
1. **Транспортные (mTLS):** Для установки защищенного соединения.
2. **Прикладные (Signing):** Для цифровой подписи реестров и платежей.
### Быстрый старт (Laravel)
1. Опубликуйте конфиг:
```bash
php artisan vendor:publish --tag=alfa-bank-config
```
2. Настройте `.env`:
```env
ALFA_BAAS_CERT_PATH=/path/to/transport.crt
ALFA_BAAS_KEY_PATH=/path/to/transport.key
ALFA_BAAS_CLIENT_ID=your_id
ALFA_BAAS_CLIENT_SECRET=your_secret
```
3. Проверьте соединение:
```bash
php artisan alfa:check
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. Авторизация и получение счетов
```php
use Apoloz\AlfaBank\Laravel\Facades\AlfaBank;
use Apoloz\AlfaBank\Requests\Accounts\GetAccountsRequest;
// SDK сам получит токен и применит его
$accounts = AlfaBank::send(new GetAccountsRequest());
foreach ($accounts as $account) {
echo $account->number . ": " . $account->openDate;
}
```
### 2. Стандартный платеж (BaaS)
```php
use Apoloz\AlfaBank\Requests\Payments\CreatePaymentRequest;
use Apoloz\AlfaBank\Data\Payments\PaymentData;
$data = new PaymentData(
amount: 1500.00,
date: date('Y-m-d'),
externalId: 'INV-2026-001',
operationCode: '01',
payeeAccount: '40702...',
payeeBankBic: '044525593',
payeeName: 'ООО Партнер',
payerAccount: '40702...',
payerBankBic: '044525593',
payerBankCorrAccount: '30101...',
payerInn: '7700000000',
payerName: 'Моя Компания',
priority: '5',
purpose: 'Оплата по счету №1'
);
$response = AlfaBank::send(new CreatePaymentRequest($data));
echo "Платеж создан: " . $response->id;
```
### 3. СБП: Генерация QR-кода
### 1. СБП: Прием платежа на номинальный счет
```php
use Apoloz\AlfaBank\Laravel\Facades\Sbp;
use Apoloz\AlfaBank\Sbp\Requests\GetQrCodeRequest;
use Apoloz\AlfaBank\Sbp\Data\QrCodeRequestData;
$payload = new QrCodeRequestData(
termNo: '90080567',
amount: '10000', // 100.00 руб
paymentPurpose: 'Заказ №5'
);
$response = Sbp::send(new GetQrCodeRequest($payload));
echo "Отсканируйте код: " . $response->payload;
```
### 4. Работа с выписками (Пагинация)
```php
use Apoloz\AlfaBank\Requests\Statement\GetTransactionsRequest;
// Автоматическая итерация через все страницы
$paginator = AlfaBank::paginate(new GetTransactionsRequest(
accountNumber: '40702...',
executeDateFrom: '2026-01-01',
executeDateTo: '2026-01-18'
$response = Sbp::send(new GetQrCodeRequest(
new QrCodeRequestData(
termNo: '90080567',
amount: '10000', // 100.00 RUB
paymentPurpose: 'Пополнение кошелька #123'
)
));
foreach ($paginator->items() as $transaction) {
echo "Транзакция {" . $transaction->uuid . ": " . $transaction->amount['amount'] . " RUB\n";
}
echo "QR URL: " . $response->dto()->payload;
```
### 5. Самозанятые (Справочники и выплаты)
### 2. Идентификация платежа (BaaS)
Когда платеж пришел на номинальный счет, его нужно привязать к бенефициару:
```php
use Apoloz\AlfaBank\Requests\SelfEmployed\GetActivitiesRequest;
use Apoloz\AlfaBank\Requests\NominalAccounts\Identification\IdentifyTransactionRequest;
use Apoloz\AlfaBank\Data\NominalAccounts\Identification\IdentifyRequestData;
use Apoloz\AlfaBank\Data\NominalAccounts\Identification\AmountDistributionData;
// Получение списка разрешенных видов деятельности
$activities = AlfaBank::send(new GetActivitiesRequest());
$data = new IdentifyRequestData(
transactionId: '1220112MOCO#DS4001415',
accountNumber: '40702810...',
amountDistribution: AmountDistributionData::collect([
['beneficiaryId' => 'BEN-001', 'amount' => '100.00']
], DataCollection::class),
digestSignatures: ... // CMS подпись
);
foreach ($activities as $activity) {
echo "{$activity->code}: {$activity->name}\n";
}
AlfaBank::send(new IdentifyTransactionRequest($data));
```
### 6. Номинальные счета (Полный цикл)
Сценарий создания бенефициара и выплаты с подписью:
### 3. Работа с номинальными счетами (Бенефициары)
```php
use Apoloz\AlfaBank\Requests\NominalAccounts\Beneficiaries\CreateBeneficiaryRequest;
use Apoloz\AlfaBank\Requests\NominalAccounts\Payouts\CreatePayoffRequest;
// 1. Создание бенефициара с CMS подписью
$response = $baas->send(new CreateBeneficiaryRequest($beneficiaryData));
// Регистрация нового бенефициара (Физлицо/Юрлицо)
$response = AlfaBank::send(new CreateBeneficiaryRequest($beneficiaryData));
$id = $response->dto()->requestId;
// 2. Инициирование выплаты
$payoff = $baas->send(new CreatePayoffRequest($payoffData));
echo "Статус выплаты: " . $payoff->dto()->status;
// Запуск скоринга (верификации)
AlfaBank::send(new ScoreBeneficiaryRequest($id));
```
---
## Продвинутые возможности
### Диагностика без Laravel
### Автоматическая пагинация
```php
use Apoloz\AlfaBank\AlfaBank;
$paginator = AlfaBank::paginate(new GetTransactionsRequest(...));
$ok = AlfaBank::check(
certificatePath: 'cert.pem',
privateKeyPath: 'key.pem',
clientId: '...',
clientSecret: '...'
);
```
### Логирование с маскировкой данных
SDK автоматически скрывает номера карт, токены и подписи в логах.
```php
$connector = AlfaBank::getFacadeRoot();
$connector->withLogging(Log::channel('daily')->getLogger());
```
### Обработка Webhooks (Laravel)
```php
// routes/api.php
Route::alfaWebhooks('/webhooks/alfa');
// Listener
public function handle(AlfaWebhookReceived $event) {
$data = $event->webhook->data;
// $data будет объектом TransactionWebhookData или SbpPaymentWebhookData
foreach ($paginator->items() as $transaction) {
// Каждая итерация автоматически подгружает следующую страницу при необходимости
}
```
---
### Webhook Handling (Laravel)
```php
// Регистрация роута
Route::alfaWebhooks('/api/alfa/webhooks');
// Обработка в Listener
public function handle(AlfaWebhookReceived $event) {
if ($event->webhook->object === 'ul_transaction_default') {
$tx = $event->webhook->data; // TransactionWebhookData
Log::info("Пришел платеж на сумму: " . $tx->amount['amount']);
}
}
```
## Лицензия
MIT. Автор: Anatoliy Poloz.
MIT. Автор: Anatoliy Poloz.