← ALL PROJECTS

PROJECT 003 · CASE STUDY

VIN View Pro

LIVESolo build (contract)2025-10-08 · PYTHON · STRIPE · GCP
VISIT LIVE ↗

A six-week contract for AutoGrab. Cloud functions that look up a vehicle by VIN or plate, take payment, and deliver the report by email, with no database at all.

Problem

AutoGrab, a vehicle data company, wanted to sell detailed car reports to the UK market: enter a VIN or number plate, see a free teaser of the vehicle, pay a fiver, get the full report by email.

The brief was small and the timeline was six weeks, which made the real engineering question one of restraint. How little infrastructure can honestly carry a paid product?

What I built

Four single-purpose Python functions on Cloud Run, each independently deployable with its own locked dependency set.

  • A free lookup endpoint that resolves a VIN or plate through the AutoGrab API and returns the vehicle plus its factory-fitted options as a teaser.
  • A checkout endpoint that creates a Stripe PaymentIntent for the embedded Elements form on the client’s WordPress frontend.
  • A webhook receiver that verifies the Stripe signature on payment success, re-fetches the vehicle data, and sends two emails through SendGrid: the report to the customer and a lead notification to the sales team.
  • A re-access endpoint that lets a customer retrieve their report later, authorised against their payment history.

Bitbucket Pipelines runs the tests on every push and deploys all four functions to Cloud Run on merge.

Decisions worth explaining

Stripe is the database. The VIN, customer details, and purchase all live in PaymentIntent metadata. “Has this customer paid for this VIN” is answered by querying Stripe, not a table I would have had to provision, secure, and back up for a product this size. It would be the wrong call at scale, and it was exactly the right call for a six-week engagement with low volume and a hard budget.

Defensive parsing for an inconsistent upstream. The vehicle API returns three different response shapes depending on region and vehicle type, including one where the details arrive as a free-text string. The parser tries each shape in turn rather than assuming the documented one, because the documented one is not always what arrives.

Webhook ordering that favours the customer. On payment success, the customer’s report email must succeed. If it fails, the function returns 500 so Stripe retries the webhook. The internal sales notification is attempted afterwards and only logged on failure, so a flaky internal email can never block or duplicate a paying customer’s report.

Outcome

Delivered in six weeks, solo, with the full lookup-pay-deliver flow live behind the client’s frontend and the price and currency configurable without a redeploy.

Stack

Python 3.12 on Cloud Run functions, Stripe PaymentIntents and webhooks, SendGrid, pip-tools lockfiles per function, Bitbucket Pipelines CI.