Stop Building Chaotic Payment Systems: A Complete Design Methodology for Payment Domains

The article presents a production‑grade, modular design methodology for payment domain systems, detailing five core modules, essential principles such as idempotency and ACID, concrete implementation examples with Kafka, Redis, PostgreSQL, and guidance on risk, compliance, and high‑availability engineering.

LuTiao Programming
LuTiao Programming
LuTiao Programming
Stop Building Chaotic Payment Systems: A Complete Design Methodology for Payment Domains

Payment Domain System Overview

Ledger must always be accurate

All operations must be idempotent

Fund operations must be ACID

Asynchronous processing with Kafka, state stored in Redis, ledger in PostgreSQL

Real‑Time Payment System (UPI / Instant Payment)

Core Goals

<2 seconds settlement

High concurrency

99.99% availability

Idempotent Payment Example

// com.icoderoad.upi.service.UpiPaymentService
@Service
public class UpiPaymentService {
    @Transactional
    public UpiTransaction initiate(UpiRequest request) {
        return repository.findByRequestId(request.getRequestId())
            .orElseGet(() -> {
                UpiTransaction txn = new UpiTransaction();
                txn.setAmount(request.getAmount());
                txn.setStatus("INIT");
                repository.save(txn);
                kafkaTemplate.send("upi-events", txn.getId());
                return txn;
            });
    }
}

Request idempotency

Transaction state machine

Circuit‑break bank interfaces

Event‑driven asynchronous handling

Card Processing System (Credit / Debit)

Credit Card Key Points

Authorization vs capture

3D Secure

Tokenization

PCI‑DSS compliance

Never store clear‑text card numbers.

Tokenization Example

// com.icoderoad.card.service.TokenService
public String tokenize(String cardNumber) {
    return UUID.randomUUID().toString();
}

Debit Card Key Points

Real‑time balance verification

PIN verification

Integration with core banking systems

Limit control

Circuit‑break

Timeout handling

Reversal mechanism

Payment Gateway (Aggregator)

The gateway aggregates multiple payment methods, routes to various providers, and performs automatic failover.

// com.icoderoad.gateway.routing.SmartRouter
public PaymentProvider select(List<PaymentProvider> providers) {
    return providers.stream()
        .max(Comparator.comparing(PaymentProvider::getSuccessRate))
        .orElseThrow();
}

Merchant KYC

Rate calculation

Automatic reconciliation

Multi‑channel disaster recovery

Wallet & Fund Account System

Balance must be absolutely correct.

Debit Operation Example

@Transactional
public void debit(Long walletId, BigDecimal amount) {
    Wallet wallet = repository.findByIdForUpdate(walletId);
    if (wallet.getBalance().compareTo(amount) < 0) {
        throw new RuntimeException("Insufficient balance");
    }
    wallet.setBalance(wallet.getBalance().subtract(amount));
}

Row/Distributed lock

Immutable ledger

Full traceability of operations

Reconciliation / Settlement System

T+1 reconciliation

Difference detection

Net settlement

File generation

Batch scheduling

Transaction matching algorithm

Exception alerts

Risk Control System

Risk control combines a rule engine with ML models.

public RiskResult evaluate(Transaction txn) {
    int score = ruleEngine.score(txn);
    return score > 80 ? RiskResult.block() : RiskResult.pass();
}

Real‑time scoring

Device fingerprinting

Frequency detection

Configurable rules

Refund / Split‑Payment / Subscription

Refund

Original‑path refund

Partial refund

Idempotent control

Split‑Payment

Multi‑party profit sharing

Delayed settlement

Subscription

Scheduled deductions

Exponential back‑off retries

Lifecycle management

Credit & EMI System

Loan application

Risk assessment

Approval workflow

Disbursement

EMI calculation & collection

EMI Calculation Example

public BigDecimal calculateEMI(BigDecimal p, BigDecimal r, int n) {
    BigDecimal monthly = r.divide(BigDecimal.valueOf(12), 10, RoundingMode.HALF_UP);
    BigDecimal factor = (monthly.add(BigDecimal.ONE)).pow(n);
    return p.multiply(monthly).multiply(factor)
            .divide(factor.subtract(BigDecimal.ONE), 2, RoundingMode.HALF_UP);
}

Common Design Principles Across All Systems

Fund Consistency First

Idempotency

ACID transactions

Saga‑based distributed transactions

Immutable ledger

Security & Compliance

PCI‑DSS

Data encryption

Tokenization

Audit logging

High Availability

Multi‑datacenter deployment

Circuit‑break

Graceful degradation

99.99% SLA

High Concurrency

Horizontal scaling

Sharding databases

Kafka for decoupling

Redis acceleration

Observability

Real‑time monitoring

Reconciliation reports

Risk alerts

Performance metrics

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

risk managementdistributed architecturepayment systemsKafkaidempotencyPostgreSQLPCI-DSS
LuTiao Programming
Written by

LuTiao Programming

LuTiao Programming is a friendly community offering free programming lessons. We inspire learners to explore new ideas and technologies and quickly acquire job-ready skills.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.