Building a Merchant Account System Class Diagram with PlantUML: A Masterclass

Architectural Context: Modeling Financial Systems with Diagram-as-Code

In the fintech and banking sectors, the complexity of merchant onboarding, transaction processing, and settlement systems requires rigorous architectural documentation. A Merchant Account System is not merely a database schema; it is a dynamic ecosystem of business rules, compliance checks, and financial flows. When designing such systems, developers and architects often struggle to communicate the relationships between entities like Settlements, Transactions, and Compliance Monitoring using static documentation.

Building a Merchant Account System Class Diagram with PlantUML: A Masterclass - Real-world system problem context illustration

Visual modeling bridges this gap. By using PlantUML within the VPasCode editor, you can transform abstract requirements into living, executable documentation. This approach ensures that your class diagrams remain synchronized with your codebase, allowing you to prototype complex inheritance hierarchies and cardinality constraints instantly without the overhead of local tooling. This tutorial guides you through constructing a robust Merchant Account System class diagram, demonstrating how to model financial entities, their attributes, and their critical inter-relationships.

Understanding the Model: Purpose, Scope & Problem Framing

Diagram Abstraction & Representation

A Class Diagram is the backbone of object-oriented system design. It captures the static structure of a system by defining classes, their attributes, methods, and the relationships that bind them. In the context of a Merchant Account System, this diagram serves as a blueprint for the backend logic. It defines:

  • Entities: Core objects like MerchantAccount, Transaction, and Settlement that hold data.
  • Behaviors: Methods such as authorizeTransaction() or calculateSettlement() that dictate system actions.
  • Relationships: How entities interact, such as a Merchant owning multiple Transactions or a Transaction being disputed via a Chargeback.

Target Domain Scope & Scenario

This model focuses specifically on the Payment Processing Lifecycle. It covers the journey from Merchant Onboarding (creating the account) to Transaction Authorization, Fraud Detection, and finally Settlement. It explicitly excludes user interface components or external network infrastructure, focusing purely on the core data model and business logic required for a payment gateway to function correctly.

Key Takeaways & Educational Insights

By building this diagram, you will gain a deeper understanding of:

  • Inheritance Patterns: How to model different merchant types (Retail, E-Commerce, Mobile) under a common abstract base.
  • Ownership Semantics: Distinguishing between Composition (strong ownership) and Aggregation (weak ownership).
  • Cardinality: Defining one-to-one, one-to-many, and many-to-many relationships accurately.

Complete Diagram & Full Source Code

Below is the complete blueprint for the Merchant Account System. This diagram utilizes the sunlust theme for a professional financial aesthetic and includes 12 distinct classes with complex relationship mappings.

Merchant Account System Class Diagram showing relationships between MerchantAccount, Transaction, Settlement, and PaymentGateway classes

@startuml

!theme sunlust
title Merchant Account System - Class Diagram

' Abstract base class
abstract class MerchantAccount {
  - accountId: String
  - accountNumber: String
  - businessName: String
  - businessType: BusinessType
  - taxId: String
  - registrationDate: Date
  - accountStatus: AccountStatus
  - balance: BigDecimal
  + deposit(amount: BigDecimal): void
  + withdraw(amount: BigDecimal): void
  + getBalance(): BigDecimal
  + {abstract} calculateSettlement(): Settlement
  + {abstract} getProcessingFees(): FeeStructure
}

' Derived classes from MerchantAccount
class RetailMerchantAccount {
  - storeLocation: String
  - posCount: Integer
  - averageTicketSize: BigDecimal
  - storeHours: String
  + calculateSettlement(): Settlement
  + getProcessingFees(): FeeStructure
  + generateSalesReport(): Report
}

class ECommerceMerchantAccount {
  - websiteUrl: String
  - platform: ECommercePlatform
  - paymentGateways: List
  - fraudPreventionLevel: String
  + calculateSettlement(): Settlement
  + getProcessingFees(): FeeStructure
  + integratePaymentGateway(): void
}

class MobileMerchantAccount {
  - mobileAppName: String
  - appStoreId: String
  - deviceTypes: List
  - mcommerceEnabled: boolean
  + calculateSettlement(): Settlement
  + getProcessingFees(): FeeStructure
  + generateMobileReport(): Report
}

' Transaction class
class Transaction {
  - transactionId: String
  - amount: BigDecimal
  - currency: String
  - transactionDate: Date
  - transactionType: TransactionType
  - authorizationCode: String
  - status: TransactionStatus
  - description: String
  + authorizeTransaction(): boolean
  + captureTransaction(): void
  + voidTransaction(): boolean
  + refundTransaction(): void
}

' Settlement class
class Settlement {
  - settlementId: String
  - settlementDate: Date
  - netAmount: BigDecimal
  - grossAmount: BigDecimal
  - feeAmount: BigDecimal
  - settlementPeriod: DateRange
  - status: SettlementStatus
  + processSettlement(): void
  + generateSettlementReport(): String
  + calculateNetAmount(): BigDecimal
}

' FeeStructure class
class FeeStructure {
  - feeId: String
  - merchantCategory: String
  - transactionFeePercentage: Double
  - transactionFixedFee: BigDecimal
  - monthlyFee: BigDecimal
  - statementFee: BigDecimal
  - chargebackFee: BigDecimal
  - currency: String
  + calculateTransactionFee(amount: BigDecimal): BigDecimal
  + getMonthlyFees(): BigDecimal
  + updateFeeStructure(): void
}

' PaymentGateway class
class PaymentGateway {
  - gatewayId: String
  - gatewayName: String
  - gatewayType: GatewayType
  - apiKey: String
  - supportedCards: List
  - processingLimit: BigDecimal
  - timeoutSeconds: Integer
  + processPayment(payment: PaymentRequest): PaymentResponse
  + validateCard(cardDetails: Card): boolean
  + handleCallback(): void
  + generateWebhook(): void
}

' Chargeback class
class Chargeback {
  - chargebackId: String
  - transactionId: String
  - amount: BigDecimal
  - reasonCode: String
  - reasonDescription: String
  - filedDate: Date
  - status: ChargebackStatus
  - resolutionDate: Date
  + fileChargeback(): void
  + respondToChargeback(): void
  + resolveChargeback(): void
  + appealDecision(): void
}

' FraudDetection class
class FraudDetection {
  - detectionId: String
  - transactionId: String
  - riskScore: Integer
  - fraudType: FraudType
  - detectionDate: Date
  - status: AlertStatus
  - investigationNotes: String
  + analyzeTransaction(): RiskScore
  + flagSuspicious(): void
  + investigateAlert(): String
  + updateFraudRules(): void
}

' MerchantReporting class
class MerchantReporting {
  - reportId: String
  - reportType: ReportType
  - generatedDate: Date
  - dateRange: DateRange
  - businessSummary: String
  - financialData: Map
  + generateDailyReport(): Report
  + generateMonthlyReport(): Report
  + generateAnnualReport(): Report
  + exportReport(format: OutputFormat): File
}

' MerchantOnboarding class
class MerchantOnboarding {
  - onboardingId: String
  - businessName: String
  - businessType: BusinessType
  - contactPerson: String
  - applicationDate: Date
  - dueDiligenceStatus: DueDiligenceStatus
  - approvalDate: Date
  + submitApplication(): void
  + performDueDiligence(): boolean
  + approveApplication(): void
  + rejectApplication(reason: String): void
}

' ComplianceMonitoring class
class ComplianceMonitoring {
  - monitoringId: String
  - merchantId: String
  - monitoringType: MonitoringType
  - startDate: Date
  - endDate: Date
  - riskLevel: RiskLevel
  - complianceStatus: ComplianceStatus
  + performKYCCheck(): boolean
  + performAMLCheck(): boolean
  + generateComplianceReport(): String
  + scheduleReview(): void
}

' ============ Relationships ============

' Generalization (Inheritance)
MerchantAccount <|-- RetailMerchantAccount
MerchantAccount <|-- ECommerceMerchantAccount
MerchantAccount <|-- MobileMerchantAccount

' Composition (MerchantAccount - Transaction) - Strong ownership
MerchantAccount *-- "0..*" Transaction : processes

' Composition (MerchantAccount - Settlement) - Strong ownership
MerchantAccount *-- "1..*" Settlement : receives

' Association (MerchantAccount - FeeStructure) - One-to-One
MerchantAccount "1" --> "1" FeeStructure : subject_to

' Association (MerchantAccount - PaymentGateway) - Many-to-Many
MerchantAccount "0..*" --> "0..*" PaymentGateway : uses

' Aggregation (Transaction - Chargeback) - Weak ownership
Transaction o-- "0..1" Chargeback : disputed_by

' Association (Transaction - FraudDetection) - One-to-One
Transaction "1" --> "0..1" FraudDetection : screened_by

' Association (MerchantOnboarding - MerchantAccount) - One-to-One
MerchantOnboarding "1" --> "1" MerchantAccount : creates

' Association (ComplianceMonitoring - MerchantAccount) - One-to-One
ComplianceMonitoring "1" --> "1" MerchantAccount : monitors

' Association (MerchantReporting - MerchantAccount) - One-to-Many
MerchantReporting "1" --> "0..*" MerchantAccount : reports_on

' Association (Settlement - MerchantReporting) - One-to-Many
Settlement "0..*" --> "1" MerchantReporting : included_in

' Association (FeeStructure - PaymentGateway) - Many-to-One
FeeStructure "0..*" --> "1" PaymentGateway : associated_with

' Association (FraudDetection - ComplianceMonitoring) - One-to-Many
FraudDetection "0..*" --> "1" ComplianceMonitoring : escalates_to

' Association (Chargeback - FraudDetection) - One-to-One
Chargeback "1" --> "0..1" FraudDetection : linked_to

' Association (MerchantOnboarding - ComplianceMonitoring) - One-to-One
MerchantOnboarding "1" --> "1" ComplianceMonitoring : requires

@enduml

Step-by-Step Architectural Walkthrough

Constructing this diagram in VPasCode involves four logical phases: setting the visual theme, defining the class hierarchy, modeling core financial entities, and mapping the relationships.

Phase 1: Canvas Configuration & Layout Directives

Every PlantUML diagram begins with configuration directives that control the visual output. For this financial system, we prioritize clarity and professional aesthetics.

We start by declaring the theme using the !theme directive. The sunlust theme provides a warm, modern color palette suitable for business applications.

!theme sunlust
title Merchant Account System - Class Diagram

Additionally, the @startuml and @enduml tags define the boundaries of the diagram, ensuring the parser knows exactly where the model begins and ends.

Phase 2: Declaring Core Entities, Actors, and Boundaries

The foundation of this system is the MerchantAccount class. Notice that we define it as abstract. This indicates that a merchant account cannot be instantiated directly; instead, it serves as a blueprint for specific types of merchants.

abstract class MerchantAccount {
  - accountId: String
  - businessName: String
  + {abstract} calculateSettlement(): Settlement
}

We then define the concrete implementations: RetailMerchantAccount, ECommerceMerchantAccount, and MobileMerchantAccount. Each inherits the core properties but adds domain-specific attributes like storeLocation or websiteUrl.

Phase 3: Mapping Data Flows & Key Interactions

The financial lifecycle revolves around Transaction and Settlement. These classes are central to the diagram. We define their attributes to capture essential financial data, such as amount, currency, and status.

The methods within these classes (e.g., authorizeTransaction, processSettlement) represent the business logic that will be implemented in the actual backend code. This ensures your documentation reflects the actual functionality.

class Transaction {
  - transactionId: String
  - amount: BigDecimal
  + authorizeTransaction(): boolean
}

Phase 4: Grouping, Annotations & Visual Polish

The final phase involves defining the relationships that bind these classes. We use specific symbols to denote the nature of the interaction:

  • Composition (*--): Used for MerchantAccount and Transaction, indicating that if the account is deleted, the transactions are also effectively removed (strong ownership).
  • Aggregation (o--): Used for Transaction and Chargeback, indicating a weaker relationship where a chargeback can exist independently or be linked to a transaction.
  • Association (-->): Used for standard links like FraudDetection and ComplianceMonitoring.

Syntax & Keyword Deep Dive

Understanding the specific PlantUML syntax is crucial for maintaining and extending your diagrams. Here are the key features used in this Merchant Account System model:

  • abstract class: Declares a class that cannot be instantiated directly. It forces subclasses to implement specific methods, ensuring a consistent interface across RetailMerchantAccount, ECommerceMerchantAccount, etc.
  • - vs +: The minus sign denotes private attributes (internal data), while the plus sign denotes public methods (accessible operations).
  • *-- (Composition): Represents a “part-of” relationship with strong lifecycle dependency. A MerchantAccount owns its Settlement records.
  • o-- (Aggregation): Represents a “has-a” relationship with weak lifecycle dependency. A Chargeback is linked to a Transaction but can exist if the transaction is archived.
  • "0..*" (Cardinality): Defines the multiplicity. "0..*" means zero or more, "1" means exactly one, and "0..1" means zero or one.
  • {abstract} Keyword: Explicitly marks a method as abstract, requiring subclasses to provide an implementation.

Best Practices & Pitfalls to Avoid

To ensure your PlantUML class diagrams remain maintainable and clear, follow these architectural best practices:

  1. Keep Diagrams Modular: Avoid placing every single class in one file. If your system grows, consider splitting the diagram into logical packages (e.g., onboarding.puml, transactions.puml).
  2. Use Meaningful Names: Avoid generic names like Entity1. Use domain-specific terms like FraudDetection or Settlement to make the diagram readable for non-technical stakeholders.
  3. Respect Cardinality: Ensure your relationship arrows match your database schema. If a merchant can have zero transactions, use "0..*", not "1..*".
  4. Separate Logic from Structure: Use the class diagram for structure and methods, but use Sequence Diagrams for complex interaction flows like payment authorization.

Start Building PlantUML Class Diagrams Faster with VPasCode

Design your financial system architecture instantly with zero setup. Test your class relationships and export professional diagrams directly from your browser.

Scroll to Top