You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This is a Kotlin Multiplatform Mobile (KMP) payment application that follows Clean Architecture principles with clear separation of concerns across multiple layers.
Architecture Layers
1. Presentation Layer
PaymentScreen.kt: Jetpack Compose UI with modern Material 3 design
PaymentViewModel.kt: MVVM pattern with StateFlow and Channel for effects
PaymentScreenState: Immutable state management
PaymentScreenEvent: Sealed class for user interactions
PaymentScreenEffect: Side effects like toasts and keyboard handling
Key Features:
Form validation with real-time error feedback
Transaction history display
Payment success dialogs
Currency selection
Accessibility support with semantic properties
2. Domain Layer (domain)
Use Cases:
SendPaymentUseCase: Orchestrates payment validation and submission
GetTransactionHistoryUseCase: Manages transaction data retrieval
Models:
Payment: Core payment entity
Transaction: Transaction data model
Currency: Enum for supported currencies
PaymentStatus: Payment state enumeration
Repositories (Interfaces):
PaymentRepository: Payment operations contract
TransactionRepository: Transaction data contract
3. Data Layer (data)
API Layer (data.api)
HttpClientFactory: Platform-specific HTTP client creation using expect/actual
Payment Models: Data classes for payment requests/responses
API Client: Ktor-based HTTP client for backend communication
Validation Logic: Email format, amount, currency validation
Firebase Integration: Firestore operations with expect/actual declarations
Business Logic: Payment processing workflows
Cross-Platform Benefits
Code Reuse: code sharing between Android and future iOS
Consistent Validation: Same business rules across all platforms
Unified API Layer: Single source of truth for backend communication
Testable Architecture: Shared tests run on all target platforms
This architecture provides excellent separation of concerns, testability, and maintainability while leveraging KMP's code sharing capabilities effectively.
🔧 Getting Started
Prerequisites
Android Studio with Kotl
8000
in Multiplatform plugin
JDK 11+ for backend services
Docker for containerized backend deployment
Firebase Project with Firestore enabled
Node.js for Appium UI testing
JMeter for API performance testing
Backend API Setup
# Start the backend servicescd backend
docker-compose up -d
# Verify API is running
curl http://localhost:8080/payments/health
Running Android App
# Install and run on device/emulator
./gradlew :androidApp:installDebug
./gradlew :androidApp:run
Running Tests
BDD Tests (Spek Framework)
# Run behavior-driven tests for shared KMP module
./gradlew shared:testDebugUnitTest --tests "com.getcashi.payment.bdd.PaymentBddSpec"# Run all Android unit tests in shared module
./gradlew shared:testDebugUnitTest
# Run with verbose output for debugging
./gradlew shared:testDebugUnitTest --tests "com.getcashi.payment.bdd.PaymentBddSpec" --info
Example scenarios covered:
Valid Payment Processing: Given valid payment details, when submitted, then payment is processed successfully and synced to Firestore
Invalid Recipient Validation: Given payment with invalid recipient email, when submitted, then validation error is returned and no Firestore sync occurs
API Server Error Handling: Given valid payment details but API server error, when submitted, then payment fails with appropriate error message
Test Structure:
Uses Spek2 framework with Gherkin-style Given/When/Then syntax
Mocks PaymentApiClient and TransactionSync dependencies
Tests SendPaymentUseCase with PaymentRepositoryImpl
Covers success paths, validation failures, and error handling scenarios
Unit Tests (JUnit/Kotest)
# Test shared KMP logic (validation, API response handling)
./gradlew :shared:test
# Test Android-specific code
./gradlew :androidApp:testDebugUnitTest