An AI portrait SaaS, finished, tested and run in production, released after it failed commercially. Laravel 11 · Livewire 3 · Filament 3 · Stripe · fal.ai.
GenPic took a photo of you, your family or your friends and turned it into a painted portrait: Renaissance oil, ukiyo-e, anime, a 1920s studio shot, a LinkedIn headshot… 73 styles in nine categories. You uploaded a photo, picked a style, saw a watermarked preview in under a minute, and paid only if you wanted the clean file.
It ran at genpic.com from March to October 2026, in five languages, taking real payments through Stripe with EU VAT handled. People generated plenty of free previews. Nobody bought one. Zero sales. Sign-ups and checkout were closed in September 2026, and in October the app was switched off; genpic.com now only hosts a short farewell page.
The code, though, was finished, tested and running in production, and binning it seemed a waste. So here it is, MIT-licensed. If you're building anything with AI image generation, paid downloads or a multilingual Laravel site, there's probably something here you can take.
The full story of the closure, in Spanish, is on the Color Vivo blog: GenPic cierra sin una sola venta y libera su código con licencia MIT.
![]() |
![]() |
Mobile: home and style page on a phone. |
More screenshots
Full-page captures: home and family photos landing.
- The full funnel: upload → face detection → moderation → AI job → polling → watermarked preview → email capture → Stripe Checkout → signed-URL delivery → automatic file purge.
- Multi-provider AI with fallback. fal.ai, OpenRouter, Novita and Evolink behind one interface, with per-provider cooldowns, a daily budget that reorders the chain cheapest-first, and the cost of every call logged.
- Stripe done properly: Checkout with Stripe Tax for EU VAT (OSS), signature-checked idempotent webhooks, and a reconciliation command every five minutes for webhooks that never arrive.
- Moderation that costs nothing per image: a Hugging Face NSFW classifier runs before any paid generation, with IP bans in Redis backed by the database.
- Five languages with translated slugs (
/fotos-de-familia,/en/family-photos,/fr/photos-de-famille…) and correcthreflang. Few sites get this right. - Filament admin with nine metric widgets, a private image viewer, GDPR anonymization, email campaigns with opt-out and a system health page.
- A written design system (docs/design.md) applied to ten landing pages, each with a different structure.
- Privacy by default: self-hosted fonts, no accounts or passwords for buyers, signed URLs for every file, and the original photo is never sent back to the browser.
- 178 tests on in-memory SQLite, run in CI on every push.
git clone https://github.com/dcarrero/genpic.git
cd genpic
cp .env.example .env
docker compose up -d --build # first run: dependencies, assets, migrations and seed
docker compose exec app php artisan key:generateOpen http://localhost:8101. Emails land in Mailpit at http://localhost:8025.
That gets you the whole site with its 73 styles and the gallery. To log into the admin, generate portraits or try the checkout without Stripe, follow docs/INSTALL.md, which also covers installing without Docker, running the tests and the usual problems.
| Service | Used for | Cost |
|---|---|---|
| fal.ai | Main image generation (SeedReam), upscaling | ≈ $0.035 per image |
| OpenRouter | Fallback generation | ≈ $0.04 per image |
| Novita, Evolink | Optional extra fallbacks (off by default) | ≈ $0.03 per image |
| Hugging Face | NSFW moderation | The free tier was enough |
| Stripe | Payments, EU VAT via Stripe Tax | Standard fees plus Stripe Tax |
| S3-compatible storage | Photos and generated images | Pennies at this scale (production used Wasabi) |
| SMTP | Transactional email | Any provider |
| Redis + MariaDB | Queues, cache, data | Your own server |
The per-image figures are the estimates in config/image_providers.php, which
feed the daily budget. Check current prices before you rely on them.
- Rewrite the legal pages. The
legal_*keys inlang/*/ui.phphold a privacy policy, terms, cookie policy and legal notice written for a Spanish company, now with placeholder company details. Treat them as a starting point, not legal advice. - Set
APP_URL,COMPANY_NAMEandCONTACT_EMAIL. - Set
ADMIN_EMAILSandADMIN_ALLOWED_IPS. ChangingADMIN_PATHonly hides the panel; the IP allowlist is what protects it. - Your own Stripe keys and webhook secret, with Stripe Tax enabled. An
empty
STRIPE_SECRETmeans simulated checkout, which in production means free orders. - At least one AI provider key with credit, and a sensible
DAILY_COST_BUDGET_USD(it reorders providers, it doesn't stop them). - A private bucket. The app never makes objects public.
- Your prices, in
database/seeders/FormatsAndProductsSeeder.phpand thepricing_price_*strings inlang/*/ui.php. - Check the style prompts against your image provider's content policy (docs/ARTISTIC_PROMPTS.md).
- Leave
CLOSED_MODE=false(the default).
Production deployment, with atomic releases, cron and Horizon, is covered in docs/DEPLOY.md.
Everything is indexed in docs/README.md: installation, configuration, deployment, customizing (styles, languages, AI providers, prices, legal pages), architecture and code conventions.
Code comments and some background documents are in Spanish: the project was built for the Spanish market first.
The service is closed and there is no roadmap. Issues and pull requests are welcome, but there's no promise of maintenance. See CONTRIBUTING.md and SECURITY.md.
Built by David Carrero Fernández-Baillo (carrero.es) at Color Vivo.
MIT © 2026 David Carrero Fernández-Baillo (carrero.es) and Color Vivo Internet S.L. (colorvivo.com)
The gallery "before" photos come from Unsplash under the Unsplash License
(credits). The fonts in public/fonts/ are
under the SIL Open Font License 1.1.


























