Benzigo

The customer-facing app with card payment for invoices, and a fleet of autonomous bots that carry out fuel-card operations on the provider's own platform.

Benzigo — B2B fuel cards Client app, card payments & portal automation Freelance · 2024–2026

benzigo.ru →

The problem

Benzigo sells fuel cards to companies running fleets: a card per vehicle, spending limits, discounts across five thousand stations. When a card is lost, a driver leaves, or an invoice goes unpaid, that card has to be blocked or frozen — now, not tomorrow.

The fuel provider's portal was built for a person clicking through it. Benzigo's CRM issues those operations by the thousand. Somebody was in the middle doing it by hand, and getting one wrong costs money in the most direct way there is: a card that should be frozen and is not keeps buying fuel, and the client pays the bill.

What I built

The customer-facing client: a Vue application packaged with Capacitor for Android and served as a progressive web app, so a fleet manager installs it straight from the browser.

Card payment inside it, against a company's outstanding invoices. The bank hosts the payment page, so no card data reaches Benzigo — but the CRM had only a stub where acquiring belonged, so the rest was mine: the order state machine, a number unique per attempt so an invoice the bank declined can be retried, and the surcharge shown before the redirect, because the amount charged is not the amount typed. The client chose to poll the bank rather than take its callback, so the write into accounting is idempotent on the bank's own order id — whichever path arrives first records the payment.

And an autonomous bot in Go that does not shuttle files but does the work: it authenticates against the provider's portal, caches the JWT in Redis, picks up XML tasks from FTP, and carries out each operation through the portal's own API — finding and validating cards, blocking, unblocking, freezing, unfreezing, reading the contract balance. Freezing is not a button there. It has to be expressed through the platform's limit system, so the bot edits limit records to produce a state the portal has no concept of.

The defensive parts earn their keep: after a failure the bot probes the card's real limit state instead of assuming it, and a failed balance read is never reported as 0,00 ₽ — the result file is what the CRM believes. Most of the 36 tests exist to protect that. It runs as a fleet of Docker instances, each with its own portal credentials, and the client runs several side by side.

The result

Thousands of card operations run through it unattended, against a portal that was never designed to be driven by anything but a human. Benzigo states it serves over a thousand client companies across more than five thousand partner stations.

Worth being precise about scope: the CRM is largely another team's work — inside it, the acquiring module is mine. So is the client the customers use, and the automation that acts on their behalf inside the provider's system.

Stack

GoRedisVueCapacitor / AndroidPHPAlfa-Bank acquiringXML over FTPDocker

Services this involved

Have a project like this?

Tell me what the system has to do and what it has to talk to. You get a straight answer about scope, sequence and what I would build first — before any commitment.

Start a conversation