From 479b9699eabe446b6b63320173b4e33f87009d50 Mon Sep 17 00:00:00 2001 From: vladtechno Date: Thu, 18 Jun 2026 20:27:39 +1000 Subject: [PATCH] feat(driver-pwa): top-up fetches commission rate from backend (no hardcoded rate) Co-Authored-By: claude-flow --- driver-pwa/frontend/src/api/driver.ts | 3 +++ driver-pwa/frontend/src/pages/TopupPage.test.tsx | 11 ++++++++++- driver-pwa/frontend/src/pages/TopupPage.tsx | 10 ++++++---- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/driver-pwa/frontend/src/api/driver.ts b/driver-pwa/frontend/src/api/driver.ts index 68dc072..19af05a 100644 --- a/driver-pwa/frontend/src/api/driver.ts +++ b/driver-pwa/frontend/src/api/driver.ts @@ -15,6 +15,7 @@ export const TopupSchema = z.object({ order_id: z.string(), pay_url: z.string(), commission: z.number(), total: z.number(), }); export const PaymentStateSchema = z.object({ order_id: z.string(), status: z.string() }); +export const CommissionSchema = z.object({ rate: z.number() }); export const PaymentsSchema = z.object({ payments: z.array(z.object({ order_id: z.string(), bucket: z.string(), amount: z.number(), commission: z.number(), @@ -35,3 +36,5 @@ export const getPaymentState = async (orderId: string) => PaymentStateSchema.parse(await api.get(`driver/payment/${orderId}`).json()); export const getPayments = async () => PaymentsSchema.parse(await api.get("driver/payments").json()); +export const getCommission = async () => + CommissionSchema.parse(await api.get("driver/commission").json()); diff --git a/driver-pwa/frontend/src/pages/TopupPage.test.tsx b/driver-pwa/frontend/src/pages/TopupPage.test.tsx index 01b367a..2e46485 100644 --- a/driver-pwa/frontend/src/pages/TopupPage.test.tsx +++ b/driver-pwa/frontend/src/pages/TopupPage.test.tsx @@ -2,14 +2,23 @@ import { describe, it, expect, vi } from "vitest"; import { render, screen } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { MemoryRouter } from "react-router-dom"; +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; vi.mock("@/api/driver", () => ({ topup: vi.fn(async () => ({ order_id: "o9", pay_url: "https://qr.nspk.ru/x", commission: 52, total: 1052 })), + getCommission: vi.fn(async () => ({ rate: 0.052 })), })); import { TopupPage } from "./TopupPage"; import * as driver from "@/api/driver"; -const wrap = () => render(); +const wrap = () => { + const qc = new QueryClient(); + return render( + + + + ); +}; describe("TopupPage", () => { it("keypad builds amount, shows total, and submits topup", async () => { diff --git a/driver-pwa/frontend/src/pages/TopupPage.tsx b/driver-pwa/frontend/src/pages/TopupPage.tsx index a213614..2c56620 100644 --- a/driver-pwa/frontend/src/pages/TopupPage.tsx +++ b/driver-pwa/frontend/src/pages/TopupPage.tsx @@ -1,14 +1,14 @@ import { useState } from "react"; import { useLocation, useNavigate } from "react-router-dom"; +import { useQuery } from "@tanstack/react-query"; import { Delete } from "lucide-react"; import { toast } from "sonner"; -import { topup } from "@/api/driver"; +import { topup, getCommission } from "@/api/driver"; import { keypadReduce, withCommission } from "@/lib/amount"; import { formatMoney } from "@/lib/format"; import { Segment } from "@/components/Segment"; import { Spinner } from "@/components/Spinner"; -const RATE = 0.052; const QUICK = ["500", "1000", "2000"]; const KEYS = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "·", "0", "back"]; @@ -19,9 +19,11 @@ export function TopupPage() { const [raw, setRaw] = useState(""); const [method, setMethod] = useState("qr"); const [busy, setBusy] = useState(false); + const { data: commission } = useQuery({ queryKey: ["commission"], queryFn: getCommission }); + const rate = commission?.rate ?? 0.052; // fallback only while loading const base = raw ? parseInt(raw, 10) : 0; - const { commission, total } = withCommission(base, RATE); + const { commission: fee, total } = withCommission(base, rate); function press(k: string) { if (k === "·") return; @@ -46,7 +48,7 @@ export function TopupPage() {

{formatMoney(base)}

- к оплате {formatMoney(total)} (комиссия {formatMoney(commission)}) + к оплате {formatMoney(total)} (комиссия {formatMoney(fee)})