Payments Backend Engineer

Srikanth

Python · PostgreSQL · Kafka · FastAPI · AWS

Two years building payment infrastructure at redBus: reconciliation across 7 gateways, dynamic gateway routing, and a UPI collect→intent migration that lifted success from ~55% to ~90%. Now building a card issuer-processor in public with a database-enforced double-entry ledger.

Money movement, ledgers, authorization, reconciliation — the systems that have to be right, not just fast.

About

Payments backend, from redBus to a card issuer-processor built in public.

I'm a payments backend engineer based in Rockville, Maryland. At redBus, India's largest online bus ticketing platform, I spent two years on the payments backend, growing from intern to full-time engineer on the team that moved money for millions of users.

The work that defined that time: a reconciliation system in Python matching internal transaction records against daily settlements from 7 payment and refund gateways, recovering shortfalls every month; migrating UPI checkout from collect to intent across all four client surfaces, lifting success from ~55% to ~90%; and dynamic gateway switching that re-evaluated live success rates every 5 minutes so checkout held steady through gateway outages and festival peaks. As an intern I traced 10–15 double-debit escalations a week to missing idempotency at the order layer — the fix eliminated that class of incident.

After an MS in Information Systems and Technology at Wilmington University, I'm building the systems I want to work on next, in public: a card issuer-processor with a database-enforced double-entry ledger, tokenized card vault, and real-time authorization, plus a multi-rail settlement reconciliation engine and a CDC-based transaction event pipeline.

I care about the parts of payments that are hard to get right — idempotency, ledger correctness, reconciliation, and what happens when a network call fails halfway through moving someone's money.

Experience

redBus — intern to payments engineer.

Two years on the payments backend of India's largest online bus ticketing platform.

Software Engineer · Payments
Feb 2022 – Jul 2023 · redBus, Bengaluru
Built payment reconciliation in Python across 7 payment and refund gateways, matching internal transaction records against daily settlements — flagged hundreds of mismatches monthly and recovered payment shortfalls worth thousands of dollars every month.

Migrated UPI checkout from collect to intent flows across all 4 client surfaces (Android, iOS, mobile web, desktop), lifting UPI success from ~55% to ~90% on the highest-volume payment method; integrated Google Pay and PhonePe.

Built dynamic gateway switching that re-evaluated live success rates every 5 minutes and routed each transaction through the best channel (UPI apps, BHIM, direct bank rails, card networks), holding success steady through gateway outages and peak traffic. Shipped a payment-failure redressal system, BIN-based card routing, and the redBus wallet (300K+ users).

Load-tested payment and booking APIs ahead of Diwali and Sankranti peaks (up to 10x normal traffic), flagging slow endpoints and bottlenecks for remediation.
Software Engineering Intern
Aug 2021 – Jan 2022 · redBus, Bengaluru
Debugged 10–15 double-debit and double-booking escalations per week, tracing them to missing idempotency at the order layer — the fix eliminated that class of incident. Supported production testing ahead of releases, wrote technical documentation mapping platform architecture and data flows, and converted to full-time.
Skills

What I've shipped with — and what I'm deepening next.

Payments

ReconciliationIdempotencyGateway routingBIN routingUPI (collect / intent)Double-entry ledgerAuthorizationSettlementTokenization

Backend

PythonFastAPISQLAlchemyPydanticREST APIsSQLC

Data & Correctness

PostgreSQLConstraints as invariantsUnique indexesTransactionsRelational design

Transaction Event Streaming

Apache KafkaDebezium (CDC)Apache FlinkDeduplicationLate-event handlingDelta Lake

Infra & Tooling

AWSDockerpytestGitHub ActionsGitGrafanaPrometheus

Deepening next

In progress
Card network flowsAuthorization enginesMulti-rail reconciliationExactly-once semantics
Projects

Building the payments stack, one tested layer at a time.

A card issuer-processor, a settlement reconciliation engine, and a transaction event pipeline — all public, all tested, all built around the same question: how do you make money movement impossible to get wrong?

01 / flagship · open source

Card Issuer-Processor

Building in public
Authorization · Transaction Processing · Ledger

A working issuer-processor — the system behind a card that decides in real time whether to approve a purchase, moves the money without ever charging twice, and keeps books that cannot go out of balance. Built the way Marqeta or Lithic would build it, at the scale one engineer can run and test end to end.

Live today
  • Double-entry ledger with a DB-enforced balance invariant
  • Tokenized card vault kept outside operational tables
  • Card lifecycle incl. one-time virtual cards
  • Schema, ledger tests, and CI on every push
Next milestones — each a tested PR
  • Authorization engine: balance, card status, MCC, velocity, decline codes
  • Idempotent auth → capture → settle → refund
  • Simulated card network driving transactions
  • Kafka events and end-of-day reconciliation
PythonFastAPIPostgreSQLKafkaDockerpytestGitHub Actions
// transaction flow
01card vaulttokenized · isolated
02authorizebalance · status · MCC · velocity
03capture → settleidempotency keys
04double-entry ledgerbalance invariant in the DB
05reconcileledger vs. settlement
02 / open source

Multi-Rail Settlement Reconciliation Engine

In progress
Settlement Matching · Mismatch Classification · Ledger

The same problem I solved at redBus across 7 gateways, rebuilt as a clean, tested system. Ingests daily settlement files from simulated gateways, matches them against a double-entry ledger, and classifies every mismatch — missing, duplicate, amount, fee, timing — with a tested rule per class. Designed so that events from different rails, with different schemas and latencies, resolve to one transaction rather than three rows someone stitches together by hand.

What it does
  • Ingests and normalizes per-gateway settlement files
  • Matches settlement rows to ledger entries
  • Classifies mismatches: missing, duplicate, amount, fee, timing
  • One tested rule per mismatch class
Next
  • Exceptions API for working the mismatch queue
  • Grafana: match rate, open exceptions, shortfall by gateway
PythonFastAPIPostgreSQLpytestGitHub Actions
// reconciliation flow
01settlement filesper gateway · T+1
02normalizeone schema across rails
03matchagainst double-entry ledger
04classifymissing · dup · amount · fee · timing
05exceptionsAPI + Grafana
03 / ms capstone · rebuilt in public

Real-Time Transaction Event Pipeline (CDC)

41 tests · CI green
Change Data Capture · Streaming · Transaction Data

Every payment system needs a reliable stream of what changed. This pipeline syncs Postgres transaction changes to a downstream transaction store without polling the source — about 6 seconds from commit to queryable in Delta Lake. Debezium reads row-level changes from the write-ahead log, Kafka carries them, and Flink handles deduplication, late-arriving events, and schema evolution.

What I built
  • Log-based CDC with Debezium + Kafka (no source polling)
  • Flink: dedup, late events, schema evolution
  • Delta Lake tables with upsert / merge logic
  • Python transaction simulator (orders, users, payments) as the source
  • 41 pytest tests against real Delta tables, not mocks
  • ruff lint and GitHub Actions CI on every push
PythonPostgreSQLDebeziumKafkaFlinkDelta LakeDockerpytestGitHub Actions
// pipeline
01Postgres WALtransaction row changes
02Debezium + Kafkalog-based CDC stream
03Flinkdedup · late events · schema
04Delta Laketransaction store · ~6s freshness
04 / where it started · b.tech final year

RFID Access-Control Event Logging

Completed · team project
Embedded C · RFID · Event Logging

My B.Tech final-year team project at JNTU Hyderabad: RFID tags in student ID cards triggered an Arduino reader at campus gates, logging each exit event and raising alerts. I wrote the reader logic and event handling in C. My first system where every tap had to be recorded exactly once.

CArduinoRFIDEmbedded Systems
// flow
01RFID tagembedded in student ID
02Arduino readergate module · C logic
03exit eventlogged + alert triggered
Notes from the build

What payments systems taught me, one lesson at a time.

A running log of the principles behind the code — the ones I learned at redBus and am now building into the issuer-processor.

Lesson 01

Idempotency belongs at the boundary

At redBus, double-debits weren't a gateway problem — retries reached the order layer with nothing to deduplicate them. Every request that can move money needs a key that makes the second attempt return the first result.

Retry is normal. Charging twice is a design failure.
Lesson 02

The database is the last line of defense

Application code can check that a ledger balances. Only a database constraint can guarantee it. In the issuer-processor the balance invariant lives in the schema, so no code path can violate it.

App validation catches mistakes. DB constraints make them impossible.
Lesson 03

Your ledger is only as true as your reconciliation

A transaction marked "success" internally means nothing until the gateway's settlement file agrees. Reconciliation across 7 gateways was how redBus found the money that would otherwise have quietly gone missing.

Internal record = what you think happened. Settlement = what actually happened.
Lesson 04

Route on live data, not assumptions

Gateway success rates drift by the hour. Re-evaluating them every 5 minutes and routing each transaction to the best channel kept checkout working through outages nobody announced.

The best gateway is whichever one is working right now.
Lesson 05

Fewer steps, more success

Moving UPI from collect to intent didn't change the payment — it removed the steps where users dropped off. Success went from ~55% to ~90% without touching a single bank integration.

Most payment failures are UX failures wearing a technical costume.
Now

Progress check

Issuer-processor: ledger, tokenized vault, card lifecycle, and CI are live. Reconciliation engine classifies five mismatch types with a tested rule each. CDC pipeline: 41 tests green on every push.

Next up: the authorization engine, then idempotent auth → capture → settle → refund.
Resume

The short version, on one page.

Payments Backend Engineer · Python · PostgreSQL · Kafka

Payments backend engineer with 2 years building payment infrastructure at redBus, India's largest bus ticketing platform: reconciliation across 7 payment gateways, dynamic gateway routing, and a UPI collect-to-intent migration lifting success from ~55% to ~90%. Now building a card issuer-processor in public with a database-enforced double-entry ledger.

Skills
Payments: reconciliation, idempotency, gateway & BIN routing, UPI, double-entry ledger · Backend: Python, FastAPI, SQLAlchemy, Pydantic, PostgreSQL, REST · Transaction Data & Event Streaming: Kafka, Debezium (CDC), Flink, Delta Lake · Infra: AWS, Docker, pytest, GitHub Actions, Grafana, Prometheus
Experience
redBus — Software Engineer, Payments (Feb 2022 – Jul 2023) · Software Engineering Intern (Aug 2021 – Jan 2022), Bengaluru, India
Projects
Card Issuer-Processor (2025 – present) · Multi-Rail Settlement Reconciliation Engine (2025 – present) · Real-Time Transaction Event Pipeline (CDC) (Dec 2024 – present)
Education & certification
MS, Information Systems and Technology — Wilmington University, May 2025 · B.Tech, ECE — JNTU Hyderabad, 2018–2022 · AWS Certified Data Engineer – Associate (2026)
Contact
srikanth.mcu@gmail.com · +1 (252) 284-5365 · Rockville, MD · linkedin.com/in/srikanth-mcu · github.com/srikanthbattula9
Contact

Let's talk payments.

Ledgers, reconciliation, authorization, gateway routing — if you're building systems that move money and need them to be right, I'd like to hear about it.