← Projects

Alahubs Checkout

Dedicated payment microservice with Stripe and Mercado Pago. Processes USD subscriptions and BRL orders with idempotency, Discord alerts and Meta Ads lead attribution.

2024ProductionFounder & Full-Stack ArchitectSaaSPaymentsFintech
  • NestJS
  • TypeScript
  • PostgreSQL
  • Stripe
  • Mercado Pago
  • Docker
  • Kubernetes
  • Meta Ads
  • Discord API
2500+ users
5k+ transactions/day
<500ms processing
Stripe + Mercado Pago

Impact

  • Isolated NestJS service from the main Alahubs platform, enabling independent payment scaling and updates without affecting user operations.
  • Stripe for USD subscriptions and Mercado Pago for BRL orders unified into a single processing endpoint. Idempotency keys prevent double-charging; nightly cron reconciles ledgers between both processors.
  • Native pg driver with 20-connection pool replacing Prisma ORM, with 15% latency improvement. Parameterized queries, atomic transactions and repository pattern for data access abstraction.
  • Real-time alerts via Discord webhook for failures and successful transactions. Lead attribution with SHA256-hashed PII sent to the Meta Pixel API.

KPIs

Entities modeled
4 (Products, Purchases, Cards, Coupons)
Connection pool
20 connections
Processors
Stripe + Mercado Pago
Average latency
<500ms
Daily transactions
5k+
Currencies supported
USD, BRL
Event integrations
Discord, Meta Ads
Coupon types
Fixed, Percentage

Traction & Growth

Active Users
2500+
Paying Customers
120+
Monthly Price
R$ 49.95 to R$ 499.95
MRR
~R$ 40k - R$ 60k
Acquisition Channel
Alahubs organic + Meta Ads
Processes all Alahubs subscription revenue. Payment success rate above 98.5%. Mercado Pago leads in LATAM markets; Stripe in US/EU. Estimated LTV $250+ based on 12-month retention.

Architecture

alahubs-checkout-architecture

Key Decisions

  • Native pg driver instead of Prisma ORM: Manual SQL increases maintenance cost, but eliminates ORM overhead and schema drift. 15% latency improvement for high-volume payment processing.
  • Repository pattern for data abstraction: One extra indirection layer, but makes testing easier and allows swapping the database without touching business logic.
  • Single payment endpoint with internal provider routing: Simplifies frontend integration, but requires careful error mapping: Stripe and Mercado Pago return completely different response formats.
  • Synchronous payment processing without a job queue: Endpoint blocks until the provider responds (latency over 500ms). Less operational complexity, but vulnerable to external API slowness. Bull or RabbitMQ would fix this.

Hard Problems

  • Stripe uses subscriptions in USD; Mercado Pago uses orders in BRL with no native subscription model. A BillingType enum and provider-specific logic inside PaymentsService handle the mapping. Mercado Pago subscriptions are emulated with recurring order creation and scheduled checks.
  • SQL queries without an ORM require manual parameter binding. Query builder utilities with strict TypeScript interfaces maintain type safety without relying on Prisma.
  • A single request can contain multiple products with different discounts. The coupon repository tracks which products each coupon applies to; the calculation sums per-product reductions before processing payment.
  • Meta Ads requires user email and name for lead attribution, but that data cannot be stored in plaintext. SHA256 hash applied at payment request time; hashed values sent to the Pixel. Raw PII never written to the database.
  • The 20-connection pool can exhaust under load. Pool metrics monitored with alerts at 80% utilization. Non-critical requests rejected gracefully when the pool is near capacity.

Ops & Runbook

  • Stripe is the primary processor; Mercado Pago is the fallback. Circuit breaker activates after 3 consecutive failures. Manual reset via /admin/circuit-breaker/reset.
  • Connection pool monitored via Datadog APM. Alert if utilization exceeds 80% for more than 5 minutes. Response: scale horizontally or investigate slow queries.
  • Discord and Meta Ads webhooks fire asynchronously after successful transactions. Retries with exponential backoff (1s, 2s, 4s). Persistent failures go to a DLQ table.
  • Product cache with 1-minute TTL. Manual invalidation via /admin/cache/invalidate?entity=products. Changes propagate to replicas within 30s.
  • Nightly cron at 03:00 UTC compares local ledger with Stripe invoices and Mercado Pago orders. Discrepancies trigger a Slack alert.

Security & Privacy

  • DTOs decorated with class-validator reject malformed requests before any processing.
  • All queries use pg parameter binding ($1, $2). Dynamic SQL concatenation not permitted.
  • Coupons identified by slug, not sequential integer IDs. Prevents brute-forcing. Creation restricted to admin endpoints with role guards.
  • Stripe secret key never hardcoded or logged. Quarterly rotation via CI/CD secrets manager.
  • All Stripe webhooks validated via sig_* header before any processing.

What I'd Improve Next

  • Replace synchronous processing with Bull or RabbitMQ queues. The endpoint would return immediately; workers would process the transaction in the background.
  • Automatic retries with exponential backoff for transient network failures without manual intervention.
  • Immutable transaction ledger for complete audit trail and dispute resolution without relying on third-party APIs.
  • Self-service portal for customers to manage invoices, payment methods and subscription tiers.