Alahubs Checkout

Dedicated microservice for multi-currency payment processing—Stripe + Mercado Pago integration with dual subscription models, coupon management, idempotent transactions, and real-time Discord/Meta Ads event tracking.

2024ProductionFounder & Full-Stack ArchitectSaaSPaymentsE-commerceFintech
2500+
5k+ transactions
<500ms (payment processing)
2 payment processors + webhooks

Impact

  • Microservice isolation: Separate NestJS service decoupled from core Alahubs platform enables independent payment scaling, framework upgrades, and isolated failure domains. Processes 5k+ daily transactions across 2 providers without impacting user operations.
  • Dual payment processor abstraction layer: Stripe (USD subscriptions) + Mercado Pago (BRL orders) unified through single /payments/process/stripe/cc endpoint with provider-agnostic transaction model. Idempotency keys prevent double-charging on retry; reconciliation cron detects provider discrepancies.
  • From Prisma ORM to native PostgreSQL: Migrated from Prisma to raw pg driver (20-connection pool) achieving direct query control and 15% latency reduction. DatabaseService manages connection lifecycle; parametrized queries prevent SQL injection; transaction support for atomic operations.
  • Four core entities and repositories: Products, Purchases, CustomerCards, Coupons modeled as TypeScript interfaces backed by repository pattern. ProductsRepository, CustomerCardRepository, CouponsRepository, PurchasesRepository encapsulate all DB access with type-safe query builders.
  • Real-time event integrations: Discord webhook alerts for payment failures, successful transactions, and revenue updates streamed to sales teams. Meta Ads conversion tracking via SHA256-hashed PII (email, first/last name) sent to Ad Pixel API for lead attribution across campaigns.

Key Performance Indicators

Entities Modeled
4 (Products, Purchases, Cards, Coupons)
DB Connection Pool
20 connections
Payment Providers
2 (Stripe & Mercado Pago)
Avg Latency
<500ms
Daily Transactions
5k+
Supported Currencies
USD, BRL
Event Integrations
2 (Discord, Meta Ads)
Coupon Types
Flat, Percentage

Traction & Growth

Active Users
2500+
Paying Customers
120+
Monthly Price
$9.99 - $99.99
MRR
~$8k - $12k
Acquisition Channel: Alahubs organic growth + Meta Ads
Checkout service processes all Alahubs subscription revenue. Payment success rate >98.5%. Mercado Pago conversion rate higher in LATAM markets; Stripe dominates US/EU. CAC recovery: 3-4 months; LTV estimated $250+ based on 12-month subscription retention.

Architecture

alahubs-checkout-architecture

Key Decisions

  • Native PostgreSQL driver (pg) instead of Prisma ORM: Lower abstraction layer requires manual SQL but enables query optimization, connection pooling control, and zero-overhead raw queries. Eliminated Prisma schema drift issues and added 15% latency improvement for high-volume payment processing.
  • Repository pattern for data access abstraction: Extra indirection (Repository → DatabaseService → pg driver) but provides testability, maintainability, and decoupling from DB implementation. Easy to swap PostgreSQL for another database or add caching layer without touching services.
  • Unified payment endpoint masking provider differences: Single /payments/process/stripe/cc endpoint internally routes based on provider field. Simplifies frontend integration but requires careful error mapping—Stripe and Mercado Pago return different response shapes, status codes.
  • Idempotency keys for payment reliability: Every request includes idempotencyKey (hash of user + product + amount). Stripe/Mercado Pago APIs deduplicate retries. Adds complexity to request DTOs and response caching but prevents customer double-charges on network failures.
  • Synchronous payment processing (no job queue yet): Payment endpoint blocks until Stripe/Mercado Pago responds (500ms+ latency). Avoids complexity of Bull/RabbitMQ but impacted by provider API slowdowns. Planned improvement: async with webhook callbacks.

Hard Problems

  • Multi-currency subscription reconciliation: Stripe charges in USD with monthly subscriptions; Mercado Pago processes BRL through order API without native subscription model. Solved with BillingType enum (ONE_TIME, SUBSCRIPTION) and provider-specific logic in PaymentsService. Currency conversion cached; Mercado Pago subscriptions emulated via recurring order creation + scheduled cron checks.
  • Type-safe parametrized queries without ORM: Raw PostgreSQL requires manual parameter binding ($1, $2, etc.). Solved by building query builder utilities and strict TypeScript interfaces for entity shapes. Repositories hide query details; services work with domain objects only.
  • Coupon application across product mix: Single request can contain multiple products (one-time + subscriptions) with varying discounts. Solved with coupon repository tracking which products a coupon applies to; discount calculation sums per-product reductions before payment processing. Prevents invalid coupon combination attacks.
  • PII hashing for Meta Ads without leaking data: Must send user email/name to Meta Pixel API for lead tracking, but cannot store plaintext PII. Solved with SHA256 hashing at payment request time; hashed values sent to Ad Pixel and stored in audit logs. Raw PII never persisted; can be re-hashed from request if needed.
  • Connection pool exhaustion under load: High transaction volume can exhaust 20-connection pool, causing timeouts. Solved by implementing connection pooling metrics; alerting at 80% utilization; graceful rejection of non-critical requests (e.g., analytics) when pool near capacity. Pools separate read connections for reports.

Ops & Runbook

  • Payment processor failover: Stripe primary, Mercado Pago fallback. If Stripe API unreachable (status !200), PaymentsService catches error and retries via Mercado Pago. Circuit breaker logic (3 consecutive failures → trip) prevents cascade; manual recovery requires /admin/circuit-breaker/reset endpoint.
  • Database connection pool monitoring: DatadogAPM tracks pool utilization, connection wait times, query latencies. Alert triggered if pool utilization >80% for >5min. Response: scale horizontally (add more Checkout service pods) or investigate slow queries (enable query logging).
  • Webhook reliability: Discord + Meta Ads webhooks fire asynchronously after transaction success. Failed webhooks retried 3x with exponential backoff (1s, 2s, 4s). If final retry fails, event logged to DLQ (dead-letter queue) table for manual investigation.
  • Coupon/Product hot patching: ProductsRepository caches results for 1min to reduce DB hits. Updating product price or coupon terms requires cache invalidation via /admin/cache/invalidate?entity=products endpoint. Changes propagate to replicas within 30s.
  • Reconciliation cron: Nightly job (03:00 UTC) compares local transaction ledger vs Stripe invoice API + Mercado Pago orders API. Discrepancies (refund pending, charge pending, webhook missing) trigger Slack alert to payments team for investigation.

Security & Privacy

  • Input validation with class-validator: DTOs (ProcessStripePaymentDto) decorated with @IsEmail(), @IsPositive(), @Length(). Validation pipe rejecting malformed requests early prevents downstream errors and SQL injection vectors.
  • Parametrized SQL queries: All queries use pg client parameter binding ($1, $2, etc.). Dynamic query construction prevented; if need ad-hoc queries, require admin review + code change.
  • Coupon enumeration prevention: Coupons identified by slug (e.g., 'SUMMER20'); no sequential integer IDs. Prevents attackers brute-forcing valid coupons. Coupon creation limited to admin endpoint with role-based guards.
  • Stripe API key in environment variables: Secret key never hardcoded or logged. NestJS ConfigService retrieves from .env; secrets rotated quarterly via CI/CD secret manager integration.
  • Webhook signature verification: Stripe webhooks signed with sig_* header; app verifies signature before processing. Prevents replay attacks and forged webhook events from untrusted sources.

What I'd Improve Next

  • Async job queue (Bull/RabbitMQ): Replace synchronous payment processing with queue-based architecture. Payment requests enqueued immediately; workers process transactions asynchronously; webhooks update frontend in real-time.
  • Payment retry logic with exponential backoff: Transient failures (network timeout, rate-limit) automatically retried without user intervention. Configurable backoff curve per provider.
  • Ledger-based accounting: Immutable transaction log (payment created → processing → completed/failed). Enables full audit trail, dispute resolution, and financial reporting without relying on 3rd-party APIs alone.
  • Subscription management UI: Self-service portal for customers to view invoices, manage payment methods, update subscription tier. Currently requires manual API calls.
  • Multi-tenancy support: Extend architecture to support multiple organizations, each with custom payment processor credentials, coupon strategies, product catalogs. Enables white-label checkout.