sashalenz / novapay-api
NovaPay Business Cabinet API client for Laravel
Requires
- php: ^8.2
- illuminate/contracts: ^10.0||^11.0||^12.0||^13.0
- spatie/laravel-data: ^4.11
- spatie/laravel-package-tools: ^1.16
Requires (Dev)
- larastan/larastan: ^3.0
- laravel/pint: ^1.14
- nunomaduro/collision: ^8.1.1||^7.10.0
- orchestra/testbench: ^8.22.0||^9.0.0||^10.0.0
- pestphp/pest: ^3.0
- pestphp/pest-plugin-arch: ^3.0
- pestphp/pest-plugin-laravel: ^3.0
- phpstan/extension-installer: ^1.3
- phpstan/phpstan-deprecation-rules: ^2.0
- phpstan/phpstan-phpunit: ^2.0
README
Laravel пакет для роботи з NovaPay Business Cabinet API v2.0.
Реалізовано всі 15 методів згідно офіційної документації «API інструкція (березень 2026)».
Встановлення
composer require sashalenz/novapay-api
Опублікуй конфіг:
php artisan vendor:publish --tag="novapay-api-config"
Конфігурація
Додай у .env:
NOVAPAY_LOGIN=your_login NOVAPAY_REFRESH_TOKEN=your_refresh_token NOVAPAY_PUBLIC_CERTIFICATE="-----BEGIN RSA PUBLIC KEY-----\n...\n-----END RSA PUBLIC KEY-----" # Необов'язково NOVAPAY_API_URL=https://business.novapay.ua/Services/ClientAPIService.svc NOVAPAY_TIMEOUT=30
refresh_token і public_certificate генеруються в особистому кабінеті:
Бізнес-кабінет → Система → Налаштування → API.
Автентифікація
JWT (рекомендований метод)
Метод використовує одноразову ротацію токенів. Кожен виклик повертає новий refresh_token і public_certificate, які треба зберігати для наступного запиту.
use Sashalenz\NovapayApi\NovapayApi; use Sashalenz\NovapayApi\NovapayCredentials; // 1. З конфігу (.env) $auth = NovapayApi::auth()->jwtFromConfig(); // 2. Явно (параметри) $auth = NovapayApi::auth()->jwt( refreshToken: 'REFRESH_TOKEN', login: 'your_login', publicCertificate: '-----BEGIN RSA PUBLIC KEY-----...', ); // 3. З DTO NovapayCredentials $credentials = new NovapayCredentials( login: $bankAccount->novapay_login, refreshToken: $bankAccount->novapay_refresh_token, publicCertificate: $bankAccount->novapay_public_certificate, ); $auth = NovapayApi::authenticateWith($credentials); // 4. Напряму з моделі (через HasNovapayCredentials інтерфейс) $auth = NovapayApi::authenticateAs($bankAccount); $jwt = $auth->jwt; // токен для API запитів $newRefreshToken = $auth->refresh_token; // зберегти в БД $newCertificate = $auth->public_certificate; // зберегти в БД
⚠️ Після кожного успішного виклику старий
refresh_tokenанульовується. Зберігай нові значення одразу після відповіді.
Інтеграція з Eloquent моделлю
Реалізуй інтерфейс HasNovapayCredentials на моделі, де зберігаються облікові дані:
use Sashalenz\NovapayApi\HasNovapayCredentials; use Sashalenz\NovapayApi\NovapayApi; class BankAccount extends Model implements HasNovapayCredentials { public function getNovapayLogin(): string { return $this->novapay_login; } public function getNovapayRefreshToken(): string { return $this->novapay_refresh_token; } public function getNovapayPublicCertificate(): string { return $this->novapay_public_certificate; } public function updateNovapayTokens(string $refreshToken, string $publicCertificate): void { $this->update([ 'novapay_refresh_token' => $refreshToken, 'novapay_public_certificate' => $publicCertificate, ]); } /** * Отримати JWT і одразу оновити токени в БД. */ public function refreshNovapayJwt(): string { $response = NovapayApi::authenticateAs($this); $this->updateNovapayTokens( $response->refresh_token, $response->public_certificate, ); return $response->jwt; } }
Використання:
$jwt = $bankAccount->refreshNovapayJwt(); $accounts = NovapayApi::accounts() ->withJwt($jwt) ->list(clientId: $bankAccount->novapay_client_id);
💡
NovapayCredentials::withUpdatedTokens()дозволяє оновити токени immutably, зберігаючи той самийlogin:$updated = $credentials->withUpdatedTokens($auth->refresh_token, $auth->public_certificate);
Легасі (буде відключено 31.08.2026)
// Крок 1 — логін + пароль $pre = NovapayApi::auth()->preAuthenticate( login: 'your_login', password: 'your_password', ); // Крок 2 — підтвердження OTP $session = NovapayApi::auth()->authenticate( tempPrincipal: $pre->temp_principal, codeOperationOtp: $pre->getCodeOperationOtp(), otpPassword: '123456', ); $principal = $session->principal; // Продовження сесії $refreshed = NovapayApi::auth()->refresh($principal); $newPrincipal = $refreshed->new_principal;
Методи API
Всі методи, окрім Auth, приймають токен через fluent-методи:
->withJwt(string $jwt) // рекомендовано ->withPrincipal(string $p) // легасі
Клієнти (підприємства)
GetClientsList — список підприємств
$response = NovapayApi::clients() ->withJwt($jwt) ->list(); foreach ($response->clients as $client) { echo $client->id; // int echo $client->name; // string echo $client->statecode; // ЄДРПОУ / РНОКПП }
Рахунки
GetAccountsList — список рахунків підприємства
$response = NovapayApi::accounts() ->withJwt($jwt) ->list(clientId: 8); foreach ($response->accounts as $account) { echo $account->id; // int echo $account->IBAN; // UA29358710... echo $account->currency; // UAH echo $account->statuscode; // AccountStatus enum echo $account->statuscode->label(); // 'Активний' }
GetAccountRest — баланс рахунку
$response = NovapayApi::accounts() ->withJwt($jwt) ->balance(accountId: 49); echo $response->confirmed_balance; // float — підтверджений залишок echo $response->available_balance; // float — доступний залишок echo $response->projected_balance; // float — прогнозований залишок
GetPaymentsList — виписка платежів (XML)
$response = NovapayApi::accounts() ->withJwt($jwt) ->payments( accountId: 49, dateFrom: '01.10.2024', // dd.mm.yyyy dateTo: '31.10.2024', dateType: DateType::PaymentDate, // enum: 0-3 ); // Рядок XML з CDATA $rawXml = $response->payments; // Або розпарсити у масив $payments = $response->parsePayments(); foreach ($payments as $p) { echo $p['Amount']; echo $p['Purpose']; echo $p['StatusDocument']; // New, Processed, ... }
GetAccountExtract — виписка з залишками (XML)
$response = NovapayApi::accounts() ->withJwt($jwt) ->extract( accountId: 49, dateFrom: '01.10.2024', dateTo: '31.10.2024', ); $data = $response->parseExtract(); // $data['head'] — масив заголовків (ExtractHead) // $data['payments'] — масив транзакцій (Docs)
GetAccountTurns — обороти по рахунку
$response = NovapayApi::accounts() ->withJwt($jwt) ->turns( accountId: 49, dateFrom: '01.10.2024', dateTo: '31.10.2024', ); foreach ($response->turns as $turn) { echo $turn->date; // '14.10.2024' echo $turn->IBAN; echo $turn->InRest; // ?float — залишок на початок echo $turn->CrncyDebit; // ?float — дебет echo $turn->CrncyCredit; // ?float — кредит echo $turn->CrncyRest; // ?float — залишок на кінець }
Платежі
CreatePayment — створення платежу
$response = NovapayApi::payments() ->withJwt($jwt) ->create([ 'account_id' => 49, 'OrgDate' => '14.11.2024', // dd.mm.yyyy 'CreditCodeIBAN' => 'UA29358700000067320000000001', 'CreditName' => 'ФОП Тест Тестовий', 'CreditStateCode' => '1234567899', 'Amount' => '1250.00', 'CurrencyTag' => 'UAH', 'Purpose' => 'Оплата за товар згідно рахунку №42', // Необов'язково: 'CreditCountry' => 'UA', 'CreditNotResident' => false, ]); if ($response->isSuccessful()) { // Платіж прийнято }
GetRecallPaymentsList — платежі доступні для відкликання
$response = NovapayApi::payments() ->withJwt($jwt) ->recallableList(); foreach ($response->payments as $payment) { echo $payment->id; // int echo $payment->orgdate; echo $payment->amount; // ?float echo $payment->debitIBAN; echo $payment->creditIBAN; echo $payment->purpose; }
RecallPayment — відкликання платежу
$response = NovapayApi::payments() ->withJwt($jwt) ->recall( paymentId: 720, info: 'Відкликання через API', // необов'язково ); echo $response->isSuccessful(); // bool
Реєстри (Post-payment / КО)
GetRegister — генерація виписки реєстру
use Sashalenz\NovapayApi\Enums\RegisterFileExtension; $response = NovapayApi::registers() ->withJwt($jwt) ->get( clientId: 8, from: '01.05.2025', into: '21.05.2025', fileExtension: RegisterFileExtension::XLS, // або CSV ); $statementId = $response->statement_id; // зберегти для download()
DownloadRegister — отримання посилання на файл
$response = NovapayApi::registers() ->withJwt($jwt) ->download(id: $statementId); echo $response->status; // 'created' — файл готовий echo $response->url; // https://...novapay.ua/files/...xlsx echo $response->file_name; // 'Реєстр переказів з 2025-05-01 до 2025-05-21.xlsx' echo $response->file_type; // 'XLS'
💡 Файл може генеруватись асинхронно. Якщо
status !== 'created'— викликайdownload()повторно через кілька секунд.
Proxy
Всі ApiModel підтримують проксі:
NovapayApi::accounts() ->withJwt($jwt) ->proxy('http://proxy.example.com:8080') ->balance(49);
Обробка помилок
Всі методи кидають NovapayApiException при HTTP помилці або невалідній SOAP відповіді.
Логічні помилки (невірний токен, нема доступу) повертаються як успішна HTTP відповідь з result = 'error':
use Sashalenz\NovapayApi\Exceptions\NovapayApiException; try { $response = NovapayApi::accounts() ->withJwt($jwt) ->balance(accountId: 49); if (! $response->isSuccessful()) { // Логічна помилка API $error = $response->error; // ?ApiError logger()->warning($error?->title, ['status' => $error?->status]); return; } // Успіх echo $response->confirmed_balance; } catch (NovapayApiException $e) { // HTTP або SOAP помилка logger()->error('NovaPay API error', ['message' => $e->getMessage()]); }
Enums
| Клас | Значення |
|---|---|
AccountStatus |
Active, Closed, OnApproval, Arrested |
DateType |
PaymentDate(0), FromDate(1), CreatedDate(2), UpdatedDate(3) |
RegisterFileExtension |
XLS, CSV |
use Sashalenz\NovapayApi\Enums\AccountStatus; AccountStatus::Active->label(); // 'Активний' AccountStatus::Active->statusCode(); // 1
Тести
composer test
Всі тести використовують Http::fake() — реальні запити до NovaPay не виконуються.
Ліцензія
MIT