wallet_debit¶
Сигнатура: wallet_debit("p_user_id" "uuid", "p_amount" numeric, "p_kind" "text" DEFAULT 'debit'::"text", "p_meta" "jsonb" DEFAULT '{}'::"jsonb") RETURNS "jsonb"
Язык: sql
Security: DEFINER
Тело функции¶
declare
cur_balance numeric;
new_balance numeric;
tx_id uuid;
begin
if p_amount is null or p_amount <= 0 then
raise exception 'INVALID_AMOUNT';
end if;
-- гарантируем кошелёк
perform public.ensure_wallet(p_user_id);
-- блокируем строку кошелька
select balance into cur_balance
from public.wallets
where user_id = p_user_id
for update;
if cur_balance is null then
raise exception 'WALLET_NOT_FOUND';
end if;
if cur_balance < p_amount then
-- не меняем баланс, просто ошибка
return jsonb_build_object('ok', false, 'error', 'INSUFFICIENT_FUNDS', 'balance', cur_balance);
end if;
new_balance := cur_balance - p_amount;
-- применяем списание
update public.wallets
set balance = new_balance, updated_at = now()
where user_id = p_user_id;
-- пишем журнал (отрицательная сумма)
insert into public.wallet_tx(user_id, amount, kind, meta)
values (p_user_id, -p_amount, coalesce(p_kind,'debit'), coalesce(p_meta,'{}'::jsonb))
returning id into tx_id;
return jsonb_build_object('ok', true, 'tx_id', tx_id, 'balance', new_balance);
end;