Alfa Bank SDK (Unofficial)

This is an unofficial PHP SDK for the Alfa Bank API, built using Saloon and Spatie Laravel Data.

Requirements

Installation

composer require apoloz/alfa-bank-sdk

Security & Setup (Crucial)

Alfa Bank uses a comprehensive security model requiring two distinct sets of keys:

  1. Transport (mTLS): To establish the SSL connection.
  2. Signing (JWS/CMS): To digitally sign the request body.

Where to get keys?

  • Sandbox: Provided by the bank support or downloaded from the Developer Portal (usually as .pfx or .zip).
  • Production:
    • Transport (mTLS): Generate a private key and CSR using OpenSSL (openssl genrsa, openssl req). Send the CSR to alfa_api@alfabank.ru. The bank will reply with your Certificate.
    • Signing: Generated by you (the client). The public certificate must be registered in "Alfa Business Online" or sent to your onboarding manager.

1. Converting PFX to PEM

If the bank provided a .pfx file for signing, you must convert it to PEM format:

# Extract Private Key
openssl pkcs12 -in signing.pfx -nocerts -out signing_key.pem -nodes

# Extract Public Certificate
openssl pkcs12 -in signing.pfx -clcerts -nokeys -out signing_cert.pem

2. Initialization

You can now initialize the SDK with both key pairs:

use Apoloz\AlfaBank\AlfaBank;
use Apoloz\AlfaBank\Enums\Environment;

$baas = AlfaBank::baas(
    // Transport Keys (mTLS)
    certificatePath: '/path/to/transport_cert.pem', 
    privateKeyPath: '/path/to/transport_key.pem',
    
    // Signing Keys (Business Logic) - Optional, defaults to transport keys if not set
    signingCertificatePath: '/path/to/signing_cert.pem',
    signingPrivateKeyPath: '/path/to/signing_key.pem',
    
    environment: Environment::SANDBOX,
    caBundlePath: '/path/to/root_ca_bundle.crt'
);

Core Usage

Authentication (BaaS)

Use the login method to perform OAuth Client Credentials flow:

$baas->login(
    clientId: 'your-client-id', 
    clientSecret: 'your-client-secret'
);

Making Requests

SBP: Generate QR Code

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

$sbp = AlfaBank::sbp(
    certificatePath: '...',
    privateKeyPath: '...',
    keyNameAlias: '9728109955', // Terminal ID
    signingPrivateKeyPath: '/path/to/signing_key.pem' // Specific signing key for SBP body
);

$response = $sbp->send(new GetQrCodeRequest(
    new QrCodeRequestData(TermNo: '...', amount: '100')
));

$link = $response->dto()->payload;

Nominal Accounts

$response = $baas->send(new CreateBeneficiaryRequest($payload));

Self-Employed (Payouts & Status)

The SDK supports managing self-employed beneficiaries, checking their FTS status, and processing payouts.

Check Taxpayer Status

use Apoloz\AlfaBank\Requests\SelfEmployed\GetTaxpayerStatusRequest;
use Apoloz\AlfaBank\Data\SelfEmployed\TaxpayerStatusRequestData;

$payload = new TaxpayerStatusRequestData(
    externalId: 'unique-id',
    selfemployedVatinList: ['123456789012']
);

$response = $baas->send(new GetTaxpayerStatusRequest($payload));
$status = $response->dto()->taxpayerStatusList[0];

Process Payout

use Apoloz\AlfaBank\Requests\SelfEmployed\CreatePayoutRequest;
use Apoloz\AlfaBank\Data\SelfEmployed\PayoutRequestData;

$payload = new PayoutRequestData(
    externalId: 'ext-id-456',
    company: ['vatin' => '7700000000'],
    requisite: [
        ['amount' => 1000, 'vatin' => '112233445566']
    ]
);
$response = $baas->send(new CreatePayoutRequest($payload));

File Exchange

Upload and download files securely.

use Apoloz\AlfaBank\Requests\FileExchange\UploadFileRequest;
use Apoloz\AlfaBank\Requests\FileExchange\DownloadFileRequest;

// Upload
$stream = fopen('path/to/file', 'r');
$baas->send(new UploadFileRequest($uploadUrl, $stream, $fileSize));

// Download
$response = $baas->send(new DownloadFileRequest($downloadUrl));
$content = $response->body();

Payments (RUR Payment Orders)

Create standard payment orders and check their status.

use Apoloz\AlfaBank\Requests\Payments\CreatePaymentRequest;
use Apoloz\AlfaBank\Data\Payments\PaymentData;

$payload = new PaymentData(
    amount: 100.50,
    date: '2023-10-25',
    externalId: 'order-12345',
    operationCode: '01',
    payeeAccount: '40702...',
    payeeBankBic: '044525225',
    payeeName: 'Partner LLC',
    payerAccount: '40702...',
    payerBankBic: '044525593',
    payerBankCorrAccount: '30101...',
    payerInn: '7700000000',
    payerName: 'My Company',
    priority: '5',
    purpose: 'Payment for services'
);

// Create Payment
$baas->send(new CreatePaymentRequest($payload));

// Check State
use Apoloz\AlfaBank\Requests\Payments\GetPaymentStateRequest;
$state = $baas->send(new GetPaymentStateRequest('order-12345'))->dto();
echo $state->bankStatus; // e.g. ACCEPTED

Cards

Retrieve a list of client cards.

use Apoloz\AlfaBank\Requests\Cards\GetCardsRequest;

$response = $baas->send(new GetCardsRequest());
foreach ($response->dto() as $card) {
    echo $card->maskedNumber . ' - ' . $card->status;
}

B2C Payouts (SBP via Phone)

Send money to individuals using their phone number through SBP.

use Apoloz\AlfaBank\Requests\B2C\CreateB2CPaymentRequest;
use Apoloz\AlfaBank\Data\B2C\B2CPaymentRequestData;
use Apoloz\AlfaBank\Data\B2C\B2CClientData;
use Apoloz\AlfaBank\Data\B2C\B2CPaymentRecipientData;

$payload = new B2CPaymentRequestData(
    client: new B2CClientData(b2cClientId: '...', partnerId: 123),
    inn: '7700000000',
    account: '40702...',
    total: 100.53,
    signedBody: '...base64_signature...',
    payments: B2CPaymentRecipientData::collect([
        [
            'phone' => '79001112233',
            'amount' => 100.53,
            'nspkBankId' => '100000000001',
            'sequence' => 'unique-seq-1',
            'name' => ['first' => 'Ivan', 'last' => 'Ivanov']
        ]
    ], DataCollection::class)
);

$baas->send(new CreateB2CPaymentRequest($payload));

Payment Registries (Batch Ruble Payments)

Create a registry for multiple ruble payments and sign it.

use Apoloz\AlfaBank\Requests\Registries\CreateRegistryRequest;
use Apoloz\AlfaBank\Data\Registries\RegistryRequestData;
use Apoloz\AlfaBank\Data\Registries\RegistryPaymentData;

$payload = new RegistryRequestData(
    payments: RegistryPaymentData::collect([
        [
            'amount' => 1000.0,
            'date' => '2023-11-01',
            'payeeAccount' => '40702...',
            'payeeBankBic' => '044525225',
            'payeeInn' => '7700000000',
            'payeeName' => 'Vendor LLC',
            'payerAccount' => '40702...',
            'purpose' => 'Batch payment part 1'
        ]
    ], DataCollection::class),
    description: 'Weekly payroll'
);

$response = $baas->send(new CreateRegistryRequest($payload));
$registryId = $response->json('id');

// Sign Registry
use Apoloz\AlfaBank\Requests\Registries\SignRegistryRequest;
use Apoloz\AlfaBank\Data\Registries\RegistrySignatureData;
use Spatie\LaravelData\DataCollection;

$signatures = RegistrySignatureData::collect([
    [
        'base64Encoded' => '...', // Base64 signature
        'signatureType' => 'RSA',
        'certificateUuid' => '...'
    ]
], DataCollection::class);

$baas->send(new SignRegistryRequest($registryId, $signatures));

Customer Info

Get organization profile.

use Apoloz\AlfaBank\Requests\CustomerInfo\GetCustomerInfoRequest;

$info = $baas->send(new GetCustomerInfoRequest())->dto();
echo $info->fullName;

Limits

Get client's operation limits.

use Apoloz\AlfaBank\Requests\Limits\GetGeneralLimitsRequest;

$response = $baas->send(new GetGeneralLimitsRequest());
$limits = $response->json();

Debit Cards

Apply for a new debit card.

use Apoloz\AlfaBank\Requests\DebitCards\CreateDebitCardApplicationRequest;
use Apoloz\AlfaBank\Data\DebitCards\DebitCardApplicationData;

$payload = new DebitCardApplicationData(
    embossingName: 'IVAN IVANOV',
    firstName: 'Иван',
    lastName: 'Иванов',
    middleName: 'Иванович',
    mobilePhone: '79001112233',
    passportBirthDate: '1990-01-01',
    sex: 'm',
    sopdConfirmed: true
);

$baas->send(new CreateDebitCardApplicationRequest($payload));

User Compliance

Check user compliance for loans.

use Apoloz\AlfaBank\Requests\Compliance\GetUserComplianceRequest;

$baas->send(new GetUserComplianceRequest());

DFA (Digital Financial Assets)

List initial placements.

use Apoloz\AlfaBank\Requests\DFA\GetDfaInitialPlacementListRequest;

$baas->send(new GetDfaInitialPlacementListRequest(limit: 5));

Currency Rates

Get currency rates by office.

use Apoloz\AlfaBank\Requests\Rates\GetOfficeRatesRequest;

$baas->send(new GetOfficeRatesRequest());

Escrow Accounts

Manage construction projects and escrow orders.

use Apoloz\AlfaBank\Requests\Escrow\GetBuildProjectsRequest;

$projects = $baas->send(new GetBuildProjectsRequest())->json();

Power of Attorney (Poa)

Request and check status of digital POAs.

use Apoloz\AlfaBank\Requests\Poa\CreatePoaRequest;

$response = $baas->send(new CreatePoaRequest('poa-123', '7700000000'));
$uuid = $response->json('requestUuid');

Loyalty

Access bonus accounts and transaction history.

use Apoloz\AlfaBank\Requests\Loyalty\GetLoyaltyAccountsRequest;

$accounts = $baas->send(new GetLoyaltyAccountsRequest())->json();

Reports

Order certificates and reports.

use Apoloz\AlfaBank\Requests\Reports\CreateAccountBalanceReportRequest;

$baas->send(new CreateAccountBalanceReportRequest(['40702...'], 'eng'));

Crypto Service

Manage encryption and signing certificates.

use Apoloz\AlfaBank\Requests\Crypto\GetCertificatesRequest;

$certificates = $baas->send(new GetCertificatesRequest())->json();

Partner (MMB)

Access partner program data and applications.

use Apoloz\AlfaBank\Requests\Partner\GetPartnerApplicationsRequest;

$apps = $baas->send(new GetPartnerApplicationsRequest())->json();

Miscellaneous

  • Bonus Numbers: $baas->send(new GetBonusNumbersRequest());
  • Credit Offers: $baas->send(new GetCreditOffersRequest());
  • Self-encashment: $baas->send(new CreateSelfEncashmentRegistryRequest($data));
  • Business Lounge: $baas->send(new GetLoungeBalanceRequest());
  • Scoring: $baas->send(new GetComplianceScoreRequest('7700000000'));
  • Security: $baas->send(new GetSubscriptionsRequest());
  • Logistics: $baas->send(new GetDeliveriesRequest('...'));
  • Webhooks: $baas->send(new GetWebhooksRequest());
  • 1C Integration: $baas->send(new CheckMerchantRequest('MF123', 'Basic ...'));
  • Claims: $baas->send(new ResolveClaimRequest('ID', $data));
  • Orders (Travel/Afisha): $baas->send(new CreateTravelOrderRequest($data));
  • Salary Project: $baas->send(new CreatePayrollApplicationRequest($payload));
  • Cloud Signature: $baas->send(new SubmitSigningRequest('REQ-ID'));
  • Aff Integration: $baas->send(new CheckComplianceRequest('INN', 'Name'));
  • Digital Ruble: $sbp->send(new CreateUniQrRequest($uniQrData));

Signing Data (CMS)

For requests requiring a digital signature (e.g., Payments), you must canonicalize and sign the data manually.

use Apoloz\AlfaBank\Utils\CmsSigner;
use Apoloz\AlfaBank\Data\NominalAccounts\Payouts\DigestSignatureData;
use Spatie\LaravelData\DataCollection;

// 1. Prepare data
$fields = [
    'amount' => 100.50,
    // ... other fields
];

// 2. Canonicalize & Sign
$json = CmsSigner::canonicalize($fields);
$cert = file_get_contents('/path/to/signing_cert.pem');
$key = file_get_contents('/path/to/signing_key.pem');
$signature = CmsSigner::sign($json, $cert, $key);

// 3. Attach to DTO
$paymentData->digestSignatures = DigestSignatureData::collect([
    [
        'base64Encoded' => $signature,
        'signatureType' => 'CMS'
    ]
], DataCollection::class);

Advanced Features

Pagination

The SDK supports automatic pagination for list endpoints:

use Apoloz\AlfaBank\Requests\Accounts\GetAccountsRequest;

$paginator = $baas->paginate(new GetAccountsRequest());

foreach ($paginator as $account) {
    // Each item is processed automatically
}

Laravel Integration

The package supports auto-discovery. Publish the config file:

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

Configure your .env:

ALFA_BAAS_CERT_PATH=/path/to/transport_cert.pem
# ... other settings
ALFA_WEBHOOK_USER=your_webhook_user
ALFA_WEBHOOK_PASSWORD=your_webhook_password

Webhook Handling (Laravel)

The SDK provides a built-in controller and route macro to handle incoming webhooks and dispatch Laravel events.

  1. Register the route in routes/api.php:
Route::alfaWebhooks('/webhooks/alfa');
  1. Listen for the event in app/Providers/EventServiceProvider.php:
use Apoloz\AlfaBank\Laravel\Events\AlfaWebhookReceived;

protected $listen = [
    AlfaWebhookReceived::class => [
        \App\Listeners\HandleAlfaWebhook::class,
    ],
];
  1. Handle the DTO in your listener:
public function handle(AlfaWebhookReceived $event)
{
    $webhook = $event->webhook; // BaseWebhookData DTO
    
    if ($webhook->object === 'ul_transaction_default') {
        $transaction = $webhook->data;
        // ...
    }
}

Error Handling

The SDK throws Apoloz\AlfaBank\Exceptions\AlfaBankException when the API returns an error.

try {
    $baas->send($request);
} catch (\Apoloz\AlfaBank\Exceptions\AlfaBankException $e) {
    echo $e->getErrorCode(); // e.g. "invalid_token" or "RQ05014"
    echo $e->getMessage();
}

Utilities

  • Card PAN Encryption: CardEncryptor::encrypt($pan, $pubKey)
  • CMS Signing: CmsSigner::sign($data, $cert, $key)
  • JWS/JWE: JwsSigner and JweEncryptor for transport security.

Diagnostics

Health Check (Laravel)

Run the built-in Artisan command to verify your mTLS certificates and connection:

php artisan alfa:check

Logging

Attach a PSR-3 logger to debug requests (sensitive data redacted):

$baas->withLogging(Log::getLogger());

License

MIT

Description
No description provided
Readme MIT 6.6 MiB
safe retry Latest
2026-09-29 07:48:09 +00:00
Languages
PHP 100%