PHPackages                             losthost/user-balance - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. losthost/user-balance

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

losthost/user-balance
=====================

A simple lib to track users' balances

0.0.6(5mo ago)09PHP

Since Dec 8Pushed 5mo agoCompare

[ Source](https://github.com/Datahider/UserBalance)[ Packagist](https://packagist.org/packages/losthost/user-balance)[ RSS](/packages/losthost-user-balance/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (6)Dependencies (2)Versions (7)Used By (0)

UserBalance Library
===================

[](#userbalance-library)

Библиотека для учета балансов пользователей с системой чекпоинтов для высокой производительности.

Особенности
-----------

[](#особенности)

- **Полная история** всех операций с фильтрацией по датам и типам
- **Высокая производительность** за счет системы чекпоинтов
- **Атомарные переводы** между пользователями в одной транзакции БД
- **Типобезопасность** через константы вместо строк
- **Поддержка больших чисел** DECIMAL(36,18) для криптовалют
- **Гибкая история операций** с пагинацией и фильтрацией

Установка
---------

[](#установка)

```
composer require losthost/userbalance
```

Быстрый старт
-------------

[](#быстрый-старт)

```
use losthost\UserBalance\DBBalanceTransaction;

// Автоматически создает таблицу при первом использовании

// Пополнение баланса
$tx = DBBalanceTransaction::transaction(
    'user_123',
    100.50,
    DBBalanceTransaction::TYPE_TOPUP,
    'Пополнение'
);

// Списание
$tx = DBBalanceTransaction::transaction(
    'user_123',
    -30,
    DBBalanceTransaction::TYPE_USAGE,
    'Оплата услуги'
);

// Перевод
$result = DBBalanceTransaction::transfer(
    'alice_id',
    'bob_id',
    50,
    'Перевод'
);

// Баланс
$balance = DBBalanceTransaction::getBalance('user_123');

// История операций
$history = DBBalanceTransaction::getHistory(
    'user_123',
    new DateTime('-7 days'), // За последние 7 дней
    null,                    // До текущего момента
    [DBBalanceTransaction::TYPE_TOPUP, DBBalanceTransaction::TYPE_USAGE],
    100,                     // Лимит
    0                        // Оффсет
);
```

Основные методы
---------------

[](#основные-методы)

### `transaction()` — Создание транзакции

[](#transaction--создание-транзакции)

```
DBBalanceTransaction::transaction(
    string $user_id,
    float $amount,
    string $type, // Используйте константы TYPE_*
    ?string $description = null
) : DBBalanceTransaction
```

### `transfer()` — Атомарный перевод

[](#transfer--атомарный-перевод)

```
DBBalanceTransaction::transfer(
    string $from_user,
    string $to_user,
    float $amount, // > 0
    ?string $description = null
) : array ['out' => $tx_out, 'in' => $tx_in]
```

### `getBalance()` — Получение баланса

[](#getbalance--получение-баланса)

```
DBBalanceTransaction::getBalance(
    string $user_id,
    ?string $datetime = null // Баланс на момент времени
) : float
```

### `getHistory()` — История операций

[](#gethistory--история-операций)

```
DBBalanceTransaction::getHistory(
    string $user_id,
    ?DateTimeInterface $start = null,
    ?DateTimeInterface $end = null,
    ?array $types = null, // null = все кроме checkpoint
    int $limit = 100,
    int $offset = 0
) : array // Массив ассоциативных массивов
```

### `checkpoint()` — Создание чекпоинтов

[](#checkpoint--создание-чекпоинтов)

```
DBBalanceTransaction::checkpoint(
    int $min_transactions // 0 = для всех пользователей
) : void
```

### `initBalance()` — Инициализация баланса

[](#initbalance--инициализация-баланса)

```
DBBalanceTransaction::initBalance(
    string $user_id,
    float $amount,
    string $description = 'Initial balance'
) : void // Бросает исключение если пользователь уже существует
```

Типы операций
-------------

[](#типы-операций)

```
DBBalanceTransaction::TYPE_TOPUP        // Пополнение
DBBalanceTransaction::TYPE_USAGE        // Списание
DBBalanceTransaction::TYPE_TRANSFER_IN  // Получение перевода
DBBalanceTransaction::TYPE_TRANSFER_OUT // Отправка перевода
DBBalanceTransaction::TYPE_CHECKPOINT   // Чекпоинт (системный)
```

**Важно:** `TYPE_TRANSFER_IN` и `TYPE_TRANSFER_OUT` можно создавать только через метод `transfer()`.

Чекпоинты для производительности
--------------------------------

[](#чекпоинты-для-производительности)

Библиотека использует чекпоинты для ускорения запросов баланса:

```
-- При запросе баланса считаются только транзакции после последнего чекпоинта
SELECT SUM(amount) FROM transactions
WHERE user_id = 'user1'
AND id >= (SELECT MAX(id) FROM transactions WHERE user_id = 'user1' AND type = 'checkpoint')
```

Рекомендуется запускать в кроне:

```
// Раз в час создавать чекпоинты для пользователей с ≥1000 транзакций
DBBalanceTransaction::checkpoint(1000);
```

Расширение функциональности
---------------------------

[](#расширение-функциональности)

### Отдельный учет бонусов

[](#отдельный-учет-бонусов)

```
class DBBonus extends DBBalanceTransaction {
    // Автоматически создаст таблицу 'bonus' с той же структурой
    // Можно добавить свои поля в METADATA
}

// Использование
DBBonus::transaction('user1', 100, DBBonus::TYPE_TOPUP, 'Бонус');
$bonus_balance = DBBonus::getBalance('user1');
```

### Кастомные типы операций

[](#кастомные-типы-операций)

```
class MyBalance extends DBBalanceTransaction {
    const TYPE_REFERRAL = 'referral';
    const TYPE_PENALTY = 'penalty';

    const METADATA = [
        ...parent::METADATA,
        'type' => 'ENUM("topup", "usage", "transfer_in", "transfer_out", "checkpoint", "referral", "penalty")',
    ];
}
```

Структура базы данных
---------------------

[](#структура-базы-данных)

```
CREATE TABLE transactions (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    user_id VARCHAR(50) NOT NULL,
    amount DECIMAL(36,18) NOT NULL,
    type ENUM('topup', 'usage', 'transfer_in', 'transfer_out', 'checkpoint'),
    description TEXT,
    created_at DATETIME NOT NULL,
    INDEX idx_user_id (user_id),
    INDEX idx_user_type (user_id, type)
);
```

Обработка ошибок
----------------

[](#обработка-ошибок)

```
try {
    DBBalanceTransaction::transfer('user1', 'user2', -10);
} catch (InvalidArgumentException $e) {
    // "Transfer amount must be positive"
}

try {
    DBBalanceTransaction::transaction('user1', 100, 'invalid_type');
} catch (InvalidArgumentException $e) {
    // "Invalid transaction type"
}

try {
    DBBalanceTransaction::initBalance('existing_user', 100);
} catch (RuntimeException $e) {
    // "User already has transactions"
}
```

Тестирование
------------

[](#тестирование)

```
composer test
```

33 теста, 85 assertions покрывают:

- Корректность расчетов баланса
- Атомарность переводов
- Работу чекпоинтов
- Фильтрацию истории операций
- Валидацию входных данных
- Создание таблиц при их отсутствии
- Проверку на работу во внешней транзакции

Производительность в продакшене
-------------------------------

[](#производительность-в-продакшене)

1. **Индексы:** `(user_id, type)` для быстрого поиска чекпоинтов
2. **Чекпоинты:** Запускайте `checkpoint(1000)` раз в час
3. **Архивация:** Старые транзакции можно перемещать в архивную таблицу
4. **Мониторинг:** Следите за количеством транзакций между чекпоинтами

Лицензия
--------

[](#лицензия)

MIT

###  Health Score

29

—

LowBetter than 59% of packages

Maintenance72

Regular maintenance activity

Popularity4

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity29

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~1 days

Total

6

Last Release

157d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/d6034471e592d56036961af1cc7ae309cdc332e5eaae18b86c2d9ecde0aae773?d=identicon)[pio](/maintainers/pio)

---

Top Contributors

[![Datahider](https://avatars.githubusercontent.com/u/29582937?v=4)](https://github.com/Datahider "Datahider (9 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/losthost-user-balance/health.svg)

```
[![Health](https://phpackages.com/badges/losthost-user-balance/health.svg)](https://phpackages.com/packages/losthost-user-balance)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
