AddisPay Payment Gateway
A production payment gateway enabling Ethiopian merchants to accept digital payments through a unified API that integrates with local banking systems and digital wallets. The platform serves hundreds of active merchants and handles real-time transaction processing with a full merchant dashboard for monitoring and reporting.
Client
Addis Pay Financial Technology
My Role
Full Stack Developer
Timeline
Nov 2023 – Sep 2024
Status
Live · Production

Ethiopian merchants had to build separate integrations for every payment provider — multiplying development cost and creating a fragmented checkout experience. AddisPay needed a single reliable gateway that any merchant could integrate in hours and trust with live transactions, plus real-time visibility into their financial operations.
A REST API layer on Node.js/Express connects merchants to the core processing engine. PostgreSQL stores all financial records with ACID guarantees. MongoDB handles flexible merchant configuration. Redis provides caching, rate limiting, and distributed locks for idempotency. A webhook dispatcher delivers real-time transaction events to merchant endpoints.
REST endpoints for payment initiation, status polling, webhook subscriptions, and merchant onboarding — documented with Swagger.
Orchestrates calls to bank and wallet providers, manages payment state machine, handles retries with exponential backoff and circuit breaking.
Redis distributed locks ensure that retried payment requests never produce duplicate charges — critical for financial correctness on unreliable networks.
PostgreSQL for transactional financial records; MongoDB for merchant config and session data; Redis for cache and rate limiting.
Real-time transaction monitoring, date-range reporting, CSV export, and balance summaries built with React and server-sent events.
- 1
Designed and implemented the core checkout API — payment initiation, status polling, and confirmation endpoints that all merchant integrations depend on.
- 2
Built the idempotency system using Redis distributed locks, preventing duplicate charges on client-side retries — the most financially critical correctness guarantee.
- 3
Optimized API response times by 40% (850ms → 510ms) through Redis caching of provider status lookups, PostgreSQL query indexing, and connection pool tuning.
- 4
Implemented the webhook dispatcher delivering real-time payment events to merchant callback URLs with automatic retry and exponential backoff.
- 5
Built the merchant-facing React dashboard with transaction tables, date-range filtering, CSV export, and real-time balance feeds using server-sent events.
Idempotent Payment Processing
Mobile clients on flaky networks retry failed requests. Without idempotency, a retry becomes a double charge. Solved with Redis-based idempotency keys: the first request acquires a distributed lock and writes the result; subsequent requests with the same key return the cached result without re-processing.
40% API Latency Reduction
Profiling showed 70% of response time came from repeated bank provider status checks returning identical results within 5-second windows. Added a short-TTL Redis cache keyed on provider + transaction ID — cutting median response from 850ms to 510ms without sacrificing freshness for time-sensitive operations.
Multi-Provider Integration Complexity
Each banking partner had a different auth scheme, error model, and webhook format. Built a provider adapter layer normalizing all external responses into a single internal Transaction model — decoupling core processing logic from upstream provider changes entirely.
Hundreds of active merchants processing live transactions daily
40% reduction in average API response time (850ms → 510ms)
Zero duplicate-charge incidents after idempotency layer deployment
Real-time webhook delivery with 99%+ success rate on 30-day rolling window
“Payment systems are 20% payment logic and 80% correctness guarantees. Idempotency, atomic state transitions, and observable failure modes are requirements, not optimizations. If I were starting this project again, the idempotency layer would be the first thing built — not the third.”