В таблице платежей меня все поля устроили, в поле опис я добавлял номера диллера/точки и т.п. - примерно 20 символов. В поле ext_id - номер сессии (20 символов). Первое что обнаружилось - поле ext_id - в базе имеет ограничение 16 символов. Этого очень мало. Пришлось добавить. Первая проверка наличия платежа/аккаунта/счета заработала без проблем. Второй пакет с платежом начал как-то странно глючить. Временами функция $payments->add возвращала ошибку 3 (SQL error) ругаясь что поле ip не может быть NULL.
Код следующий:
Код: Выделить всё
my $sql = Abills::SQL->connect($conf{dbtype}, $conf{dbhost}, $conf{dbname}, $conf{dbuser}, $conf{dbpasswd});
my $db = $sql->{db};
my $admin = Admins->new($db, \%conf);
$admin->info($conf{SYSTEM_ADMIN_ID}, { IP => $cip});
$payments->addcplat($user, $cip, {SUM => $info{AMOUNT},
DESCRIBE => "$info{AP}/$info{OP}/$info{SD}",
METHOD => '1',
EXT_ID => "$info{SESSION}",
ER => 1 });
if ($payments->{errno})
{
my $dberr = DBI::errstr;
syslog('info', "Error: pay:$cip:$info{SESSION} -> AErr=($payments->{errno}), $dberr / $cip");
$info{ERRMSG} = "ERROR ICODE $payments->{errno}";
$info{error} = 30;
}
Результат ошибки был весьма веселый - в функции add в оригинальной версии модуля запрос
"INSERT INTO payments" на ошибки не проверяется вообще и сразу за ним идет запрос на добавление денег на счет, который проходит без проблем:
Код: Выделить всё
$Bill->info( { BILL_ID => $user->{BILL_ID} } );
$Bill->action('add', $user->{BILL_ID}, $DATA{SUM});
if($Bill->{errno}) { return $self; }

Хотелось бы пожелать уважаемому автору, написавшему довольно неплохую систему биллинга все-таки не оставлять без проверки ошибок код, работающий с деньгами. И если какие-то операции требуют несколько последовательных операций с базой делать это все в транзакции и в случае ошибки откатывать всю транзакцию + выдавать ошибку. Если же платеж уже проведен, а добавить его в базу не получается по каким-то причинам его надо складывать в отельный каталог в виде файлов для последующей ручной проверки.
Примерный вариант работы в транзакции (begin_work временно отключает авто-коммит и запускает транзакцию):
Код: Выделить всё
my $sql = Abills::SQL->connect(...);
my $db = $sql->{db};
$rc = $db->begin_work;
.....
if (error) {
$db->rollback;
} else {
$db->commit;
}