forked from apoloz/alfa-bank-sdk
179 lines
6.6 KiB
Markdown
179 lines
6.6 KiB
Markdown
# Alfa Bank SDK (Unofficial)
|
||
|
||
Профессиональная PHP-библиотека для интеграции с API Альфа-Банка (BaaS и СБП). Построена на базе [Saloon v3](https://docs.saloon.dev) и [Spatie Laravel Data](https://spatie.be/docs/laravel-data).
|
||
|
||
## Требования
|
||
|
||
- PHP 8.2+
|
||
- [Saloon](https://docs.saloon.dev) v3.0+
|
||
- [Spatie Laravel Data](https://spatie.be/docs/laravel-data)
|
||
|
||
## Подключение и Безопасность
|
||
|
||
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 (Номинальные счета)
|
||
|
||
**Шаги для получения доступа:**
|
||
1. Регистрация в личном кабинете партнера.
|
||
2. Получение `client_id` и `client_secret` для OAuth2.
|
||
3. Регистрация публичного ключа для проверки подписей выплат.
|
||
|
||
**Поток данных и подпись:**
|
||
* **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 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. СБП: Прием платежа на номинальный счет
|
||
```php
|
||
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)
|
||
Когда платеж пришел на номинальный счет, его нужно привязать к бенефициару:
|
||
|
||
```php
|
||
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. Самозанятые (Регистрация доходов)
|
||
```php
|
||
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 ссылки:
|
||
```php
|
||
use Apoloz\AlfaBank\Requests\Files\UploadFileRequest;
|
||
|
||
$file = fopen('document.pdf', 'r');
|
||
$uploadUrl = 'https://baas.alfabank.ru/filebox/...'; // Получено из метода создания бенефициара
|
||
|
||
AlfaBank::send(new UploadFileRequest($uploadUrl, $file));
|
||
```
|
||
|
||
---
|
||
|
||
## Продвинутые возможности
|
||
|
||
### Управление возвратами СБП
|
||
Просмотр всей истории попыток возврата по транзакции:
|
||
```php
|
||
$response = Sbp::send(new GetQrcReversalHistoryRequest($payrrn, $termNo));
|
||
foreach ($response->dto()->refunds as $refund) {
|
||
echo "Статус возврата: " . $refund->status;
|
||
}
|
||
```
|
||
|
||
### Webhook Handling (Laravel)
|
||
```php
|
||
// Обработка СБП уведомлений в Listener
|
||
public function handle(AlfaWebhookReceived $event) {
|
||
if ($event->webhook->isSbp()) {
|
||
$data = Sbp::parsePaymentNotification($event->webhook->payload);
|
||
Log::info("СБП Оплата: {$data->amount} коп.");
|
||
}
|
||
}
|
||
```
|
||
|