DEV Community

Cover image for Building a Centralized Payment Integration Framework for Emerging Payment Technologies
Mehal C
Mehal C

Posted on • Edited on • Originally published at Medium

Building a Centralized Payment Integration Framework for Emerging Payment Technologies

A baseline framework for integrating multiple payment service providers (PSPs) supporting credit cards, digital wallets, BNPL services, and bank transfers into checkout and payment processing flows.


Introduction

Integrating and supporting multiple Payment Service Providers (PSPs) is one of the most complex challenges in fintech. Companies switch or adopt multiple PSPs to optimize cost, performance, reliability, compliance, and global coverage as they scale. How do you build a system that standardizes this complexity without tightly coupling your business logic to individual PSP?

This framework is designed for e-commerce platforms, SaaS businesses, marketplaces, fintech applications, and platform companies that need to integrate multiple Payment Service Providers (PSPs) supporting diverse payment methods - such as digital wallets (Apple Pay, Google Pay), credit cards, BNPL services, and emerging crypto payments - without building and maintaining separate integrations for each provider. It operates as an orchestration layer above individual PSP integrations, enabling unified patterns for reliability (resilience and failover), cost optimization, idempotency, fraud management, and compliance.

Key Benefits:

Vendor Independence: Not locked into a single PSP — easily switch or add new providers without rewriting core business logic.
Cost Optimization: Intelligently routes transactions to the most cost-effective PSP based on fees, success rates, and regional performance.
High Availability: Automatic failover to backup PSPs during outages or degradation, ensuring uninterrupted payment processing.
Duplicate Charge Prevention: Built-in idempotency guarantees prevent duplicate charges caused by network retries, webhook replays, or user double-submissions.
Unified Fraud Detection: Detects fraud signals both within individual PSPs and across multiple providers (e.g., Stripe, PayPal, Adyen), identifying high failure rates and velocity attacks within a single PSP as well as Cross-PSP fraud patterns such as gateway hopping, distributed velocity attacks, and card testing that individual PSPs may miss
Fraud Protection: ML-based risk scoring analyzes payments in near-real-time and sends alerts when fraud is detected.
Compliance & Audit: Automatic event logging and audit trails for regulatory compliance and transaction tracking.
Scalable by Design: Start with a single PSP and seamlessly expand to multiple providers as the business grows — the framework absorbs the added complexity.

Note: For implementation details, see the GitHub repository.

What you'll learn:

  • How to design a pluggable PSP (Payment Service Provider) architecture
  • Implementing idempotency to prevent duplicate charges
  • Building resilient systems with circuit breakers and retry logic
  • Creating an event-driven architecture for audit and compliance

The Problem: Why Payment Integration is Hard?

Payment integration isn't just about calling an API. Real-world challenges include:

  • PSP Diversity: Each PSP has unique APIs, error codes, and behaviors
  • Reliability: Network failures, PSP outages, and timeouts are common
  • Idempotency: Retries and duplicate requests can result in double charges
  • Compliance: Audit trails, transaction logging, and regulatory requirements
  • Scalability: Handling millions of transactions with low latency

Emerging Payment technologies Add Complexity

Beyond traditional card payments, emerging payment methods introduce additional challenges:

  • BNPL (Buy Now Pay Later): Installment tracking, credit checks, partial refunds, and multi-stage payment flows (e.g., Afterpay, Klarna)
  • Cryptocurrency: Price volatility, blockchain confirmation times, gas fees, and wallet address validation
  • Digital Wallets: Tokenization, device-specific authentication (Apple Pay, Google Pay), and wallet provider callbacks
  • Bank Transfers: ACH/SEPA processing delays, settlement times, and reversal handling

While each payment type requires specialized handling, they share common foundational requirements — idempotency, resilience, auditability, fraud detection, and cost optimization. This centralized framework provides a unified architecture that standardizes these cross-cutting concerns, while still allowing provider- and method-specific implementations where specialized behavior is required.


Architecture Overview

This framework consists of two main components:

  • Payment Integration Framework — Handles payment execution, idempotency, and resilience
  • Risk & Fraud Detection System — Near-real-time risk scoring using rules and ML

The architecture follows an event-driven pattern where payment execution is synchronous (for immediate response), while risk evaluation happens asynchronously via Kafka events. This separation ensures payment processing isn’t blocked by risk analysis, maintaining low latency for end users.


Payment Integration Framework

Payment Flow Sequence

Payment Integration framework flow

1. Pluggable PSP Pattern (Adapter Pattern)

The foundation of our framework is the PSPAdapter interface, which allows us to plug in any PSP without changing core logic. This follows the Adapter Pattern, where different PSPs are wrapped by adapters that translate between the framework's standard interface and each provider's specific API.

Payment Service Providers(PSPs) have vastly different APIs: PayPal has SOAP and REST endpoints, BNPL providers require multi-step flows, and crypto payments need blockchain integration. The pluggable pattern abstracts these differences, allowing new PSPs to be added without changing core orchestration logic.

The Interface Design

The PSPAdapter interface defines a contract that all payment PSP adapters must implement. It requires PSP adapters to specify their type, execute payments, and optionally report health status.

Key Benefits

  • Extensibility: Adding a new PSP (e.g., Square, Adyen) requires only implementing this interface. The orchestrator automatically discovers and routes to it.
  • Testability: Mock adapters can be injected for testing without external dependencies.
  • Consistency: All PSP adapters implement the same contract, ensuring uniform error handling, retries, and circuit breaker behavior across all PSPs.
  • PSP Isolation: Failures in one PSP don't affect others. Each PSP has its own circuit breaker instance.

PSP Discovery

The orchestrator uses Spring's dependency injection to automatically discover all PSPAdapter implementations. At startup, it builds a map from provider type to PSP adapter instance, enabling O(1) lookup during payment execution.

Provider Type Safety & Intelligent Routing (Strategy Pattern)

The router filters adapters by provider type (e.g., CARD, BNPL, CRYPTO) and circuit breaker state (healthy adapters only) then applies routing strategies (weighted round-robin, least connections, cost-based, response time-based, and hybrid routing) to select the optimal PSP from the filtered set. The routing strategy is selected via configuration payment.routing.strategy, allowing merchants to switch algorithms without code changes.

Complete Implementation: PSPAdapter.java and MockPSPAdapter.java.


2. Idempotency: Preventing Duplicate Charges

Network retries, user double-clicks, or system failures can cause the same payment to be processed multiple times, resulting in duplicate charges. We solve this with Redis-backed idempotency keys.

The IdempotencyService handles the cache logic. It checks Redis for existing results using the idempotency key. If found, it returns the cached result immediately. If not found, it proceeds with payment execution and stores the result in Redis with a 24-hour TTL.

Key Design Decisions

Fail-open: If Redis is down, we treat it as a cache miss and keep processing payments so availability isn’t blocked; we favor availability over strict idempotency when the cache is unavailable.
TTL: Keys expire after 24 hours so Redis doesn’t grow without bound, which keeps memory and cost under control while still covering typical retries and duplicate windows

  • Fail-Open Behavior: If Redis fails, we treat it as a cache miss rather than blocking requests. This ensures payment processing continues even if the cache is unavailable, prioritizing availability over perfect idempotency guarantees.
  • TTL Strategy: 24-hour TTL prevents Redis from storing keys indefinitely. Without TTL, keys accumulate forever, consuming memory and increasing costs. The 24-hour window balances preventing duplicates (covers most retry scenarios) while automatically cleaning up old data.

Integration with Payment Orchestrator

The orchestrator integrates idempotency checks before executing any payment. This ensures duplicate requests are caught before they reach PSPs.

Complete Flow: PaymentOrchestrator.java.


3. Resilience Patterns: Circuit Breakers & Retry Logic

PSPs can fail. Network issues, outages, or rate limits can cause temporary failures. We need resilience patterns that retry transient failures, fail fast when PSPs are down, and prevent cascading failures.

Circuit Breaker Pattern

The circuit breaker monitors PSP health. When failures exceed a threshold (e.g., 50% failure rate), it "opens" and immediately fails requests without calling the PSP. This enables:

  • Fail fast: Detect failures in milliseconds instead of waiting for timeouts
  • Intelligent failover: Skip broken PSPs and route to healthy ones immediately
  • Prevent cascading failures: Protect your system from being overwhelmed

Example: If Stripe's circuit breaker opens, the framework immediately routes to PayPal without attempting Stripe, reducing latency from 30+ seconds to milliseconds.

Retry Logic with Exponential Backoff

Not all failures are permanent. Network glitches and temporary timeouts are often transient—retrying after a delay can succeed. We retry with exponential backoff (1s, 2s, 4s delays) and jitter to:

  • Recover from transient errors without overwhelming the PSP
  • Prevent thundering herd problems (jitter spreads out retries)
  • Improve success rates for payments that would otherwise fail

Implementation

Using Resilience4j, we apply the decorator pattern to each PSP call with both retry and circuit breaker. Each PSP has its own circuit breaker instance, allowing independent failure handling and failover between PSPs of the same provider type(CARD, WALLET, BNPL, etc).


4. Event-Driven Architecture with Kafka

Every payment event is published to Kafka for:

  • Audit trails
  • Compliance
  • Downstream processing

Events are asynchronously published to Kafka both before and after payment execution.

Architectural Benefits

  • Low Latency
  • Horizontal Scaling
  • Durability & Replay
  • Compliance

Real-Time Risk & Fraud Detection

Risk and fraud detection flow

Transaction Window Aggregation

The TransactionWindowAggregator computes metrics (velocity, failure rate, average amount, max amount) over rolling time windows (5-minute window, 1-minute velocity) per entity (merchant/customer) — aggregates events from single PSP or across multiple PSPs for comprehensive fraud and risk analysis.


Hybrid Risk Scoring: Rules + ML

The risk engine uses ML scoring when available, with rule-based fallback. If the risk score exceeds the threshold, an alert is generated.


Extending the Architectural Framework for Production

When extending this framework for production use, you would need to add:

  • Security
  • Observability
  • Multi-Region
  • Persistence for Compliance & Audit logs

Explore the Code

Repository: Payment Integration Framework

Key Files to Explore

Top comments (0)