Version: 1.0.0
Last Updated: November 13, 2025
Status: ✅ Production Ready
- Overview
- System Architecture
- Core Features
- Commission Structure
- Payment Flow
- API Endpoints
- Integration Guide
- Data Models
- User Roles & Permissions
- Error Handling
- Security Features
- Testing Guide
- Deployment
- Support & Resources
The JobSphere Payment System is a comprehensive escrow-based payment platform designed for service marketplaces. It facilitates secure transactions between customers and contractors with automated commission handling, real-time notifications, and complete transaction tracking.
- Escrow-Based Security: All payments are held in escrow until job completion
- Automated Commissions: Platform fees and service fees are automatically calculated and distributed
- One Offer Per Job: Simplified workflow with single offer acceptance
- Automatic Refunds: Failed transactions and cancellations trigger instant refunds
- Real-Time Updates: WebSocket integration for instant notifications
- Transaction History: Complete audit trail of all financial activities
- Withdrawal Support: Contractors can withdraw earnings with configurable limits
The payment system consists of several interconnected modules:
Wallet Management
- Handles user balances (available and escrow)
- Processes deposits and withdrawals
- Tracks lifetime earnings and spending
- Supports wallet freeze functionality
Offer System
- Manages job offers between customers and contractors
- Enforces one-offer-per-job rule
- Handles offer acceptance and rejection
- Implements automatic expiration (7 days)
Transaction Engine
- Records all financial movements
- Supports multiple transaction types
- Maintains complete audit trail
- Handles failed transaction recovery
Job Payment Integration
- Links jobs with payment processing
- Manages job status transitions
- Triggers payment releases
- Handles cancellations and refunds
Admin Service
- Auto-creates admin user and wallet
- Manages commission collection
- Provides system-wide payment oversight
- Supports environment configuration
Automated Jobs
- Offer expiration cron job (runs hourly)
- Automatic refund processing
- Notification dispatch
- Application status reset
Each user has a dedicated wallet with two balance types:
Available Balance
- Money available for sending offers or withdrawal
- Updated on deposits, refunds, and payments received
- Protected from unauthorized access
Escrow Balance
- Money held for pending offers
- Released on job completion or offer rejection
- Separate from available funds for transparency
Transaction History
- Complete record of all wallet activities
- Filterable by transaction type
- Paginated for performance
- Includes sender and receiver details
Deposit Functionality
- Minimum deposit: $10
- Integrated with payment gateways
- Instant balance updates
- Transaction logging
Withdrawal System (Contractors Only)
- Minimum withdrawal: $10
- Maximum withdrawal: $10,000
- Estimated arrival: 2-3 business days
- Requires sufficient available balance
- Blocked if wallet is frozen
Sending Offers (Customer Only)
- Specify job amount, timeline, and description
- Automatic commission calculation
- Instant escrow hold
- One offer per job enforcement
- Balance validation before processing
Accepting Offers (Contractor Only)
- Reviews offer details and earnings breakdown
- Accepts to start job
- Triggers platform fee transfer to admin
- Updates job status to "assigned"
- Rejects other pending applications
Rejecting Offers (Contractor Only)
- Provides rejection reason
- Triggers full refund to customer
- Resets application status
- Allows customer to send new offer
- Sends notification to customer
Automatic Expiration
- Offers expire after 7 days
- Automated hourly check
- Full refund on expiration
- Application status reset
- Notification to customer
Job Status Flow
- Open: Accepting applications
- Assigned: Offer accepted, contractor assigned
- In Progress: Work actively being performed
- Completed: Work finished, payment released
- Cancelled: Job cancelled, refunds processed
Payment Release (On Completion)
- Service fee transferred to admin
- Contractor payout transferred to contractor
- Escrow released
- Transaction records created
- Notifications sent to all parties
Job Cancellation
- Available before completion
- Full refund to customer if offer exists
- Escrow released immediately
- Cancellation reason recorded
- Notifications to affected parties
Platform Fee (5%)
- Charged when customer sends offer
- Transferred to admin when offer accepted
- Non-refundable after acceptance
- Covers platform operating costs
Service Fee (20%)
- Deducted from job amount
- Transferred to admin on job completion
- Applied to contractor payout calculation
- Covers transaction processing and support
Total Admin Commission (25%)
- Combined platform fee and service fee
- Distributed at different transaction stages
- Transparent calculation and display
- Auditable through transaction history
Real-Time Notifications (WebSocket/Socket.IO)
- Offer received
- Offer accepted/rejected
- Payment released
- Offer expired
- Withdrawal processed
Push Notifications (FCM)
- Mobile app integration
- Critical payment events
- Configurable per user
- Device token management
For a $100 job:
| Component | Amount | Recipient | Timing |
|---|---|---|---|
| Job Budget | $100.00 | N/A | Initial |
| Platform Fee (5%) | $5.00 | Admin | Offer Acceptance |
| Total Charge | $105.00 | Customer Pays | Offer Sent |
| Service Fee (20%) | $20.00 | Admin | Job Completion |
| Contractor Payout (80%) | $80.00 | Contractor | Job Completion |
| Admin Total (25%) | $25.00 | Admin | Combined |
- Posts job with $100 budget
- Pays $105 total (includes 5% platform fee)
- $105 held in escrow when offer sent
- $0 refunded if job completed
- $105 refunded if offer rejected or cancelled
- Sees $100 job offer
- Knows they'll receive $80 (after 20% service fee)
- Receives $80 on job completion
- Can withdraw earnings anytime
- Minimum withdrawal $10
- Receives $5 when offer accepted (5% platform fee)
- Receives $20 when job completed (20% service fee)
- Total commission: $25 per $100 job (25%)
- Auto-transferred to admin wallet
- Tracked in transaction history
Step 1: Customer Preparation
- Customer registers and logs in
- Deposits money into wallet (e.g., $200)
- Posts job with budget (e.g., $100)
- Waits for contractor applications
Step 2: Contractor Application
- Contractor finds job
- Submits application with message
- Application visible to customer
- Status: "pending"
Step 3: Offer Creation
- Customer reviews applications
- Selects preferred contractor
- Sends offer with amount, timeline, description
- System calculates commissions:
- Job budget: $100
- Platform fee: $5
- Total charge: $105
- Service fee: $20
- Contractor payout: $80
- Customer wallet: $200 - $105 = $95 available
- Escrow balance: $105
- Offer status: "pending"
Step 4: Offer Response
Option A: Acceptance
- Contractor reviews offer
- Accepts offer
- Platform fee ($5) transferred to admin
- Job status changes to "assigned"
- Contractor assigned to job
- Other applications rejected automatically
- Remaining $100 stays in escrow
- Notifications sent
Option B: Rejection
- Contractor reviews offer
- Provides rejection reason
- Full $105 refunded to customer wallet
- Customer wallet: $200 available
- Application status: "pending"
- Customer can send new offer
- Notification sent to customer
Step 5: Work Execution
- Contractor updates status to "in_progress"
- Performs work according to timeline
- Communicates with customer
- Prepares for completion
Step 6: Job Completion
- Customer marks job as complete
- Service fee ($20) transferred to admin
- Contractor payout ($80) transferred to contractor
- Escrow released
- Job status: "completed"
- Offer status: "completed"
- Transaction records created
- Notifications sent
Step 7: Withdrawal (Optional)
- Contractor has $80 available
- Requests withdrawal (e.g., $50)
- System validates balance
- Processes withdrawal
- Estimated arrival: 2-3 business days
- Transaction recorded
Job Cancellation
- Customer or admin cancels job
- Cancellation reason recorded
- If offer exists: Full refund to customer
- Escrow released
- Job status: "cancelled"
- Notification to contractor
Offer Expiration
- Offer reaches 7-day limit
- Automated job identifies expired offer
- Full refund to customer
- Application status reset
- Notification sent
- Customer can send new offer
All endpoints except public routes require JWT authentication via Bearer token:
Authorization: Bearer <access_token>
Content-Type: application/json
GET /api/wallet
Authentication: Required
Returns: User's wallet with available and escrow balances
POST /api/wallet/deposit
Authentication: Required
Body: amount (number), paymentMethodId (string)
Validation: Minimum $10
Returns: Updated wallet and transaction details
POST /api/wallet/withdraw
Authentication: Required (Contractors only)
Body: amount (number)
Validation: Min $10, Max $10,000, sufficient balance
Returns: Withdrawal confirmation and new balance
GET /api/wallet/transactions
Authentication: Required
Query Parameters: page, limit, type (optional)
Returns: Paginated list of transactions
POST /api/job-request/:applicationId/send-offer
Authentication: Required (Customer only)
Body: amount (number), timeline (string), description (string)
Validation:
- Amount: $10-$10,000
- Timeline: 1-100 characters
- Description: 10-1000 characters
Returns: Offer details, wallet balance, commission breakdown
POST /api/job-request/offer/:offerId/accept
Authentication: Required (Contractor only)
Returns: Updated offer, job status, payment breakdown
POST /api/job-request/offer/:offerId/reject
Authentication: Required (Contractor only)
Body: reason (string, optional)
Returns: Updated offer status, refund amount
PATCH /api/job/:id/status
Authentication: Required
Body: status (string)
Valid Transitions:
- open → assigned, cancelled
- assigned → in_progress, cancelled
- in_progress → completed, cancelled
Returns: Updated job details
POST /api/job/:id/complete
Authentication: Required (Customer only)
Prerequisites: Job must be "in_progress"
Returns: Completed job details, payment breakdown
POST /api/job/:id/cancel
Authentication: Required (Customer or Admin)
Body: reason (string, optional)
Returns: Cancelled job details, refund amount
Service Setup
- Create service classes for wallet, offers, and jobs
- Implement centralized API client with interceptors
- Handle authentication tokens securely
- Add error handling middleware
Wallet Integration
- Display available and escrow balances prominently
- Show deposit and withdrawal options
- Implement transaction history view with filtering
- Add balance refresh on navigation
Offer Flow UI
- Create offer dialog with commission breakdown
- Show real-time balance validation
- Display contractor earnings calculation
- Add confirmation steps
Job Management
- Implement status badges with color coding
- Add complete/cancel buttons based on role
- Show payment status in job details
- Handle status transitions with confirmation
Error Handling
- Display user-friendly error messages
- Handle insufficient balance gracefully
- Show loading states during transactions
- Implement retry mechanisms
Real-Time Updates
- Integrate Socket.IO client
- Listen for payment events
- Update UI on notifications
- Show toast/snackbar for events
Service Layer
- Create Dart service classes
- Use http package for API calls
- Implement secure token storage (flutter_secure_storage)
- Add error handling and retries
Wallet Features
- Design wallet widget with balance display
- Implement deposit flow with payment gateway
- Add withdrawal screens with validation
- Show transaction history with pagination
Offer Management
- Create offer cards with expandable details
- Implement accept/reject dialogs
- Show commission breakdown clearly
- Add confirmation flows
Push Notifications
- Integrate Firebase Cloud Messaging (FCM)
- Register device token with backend
- Handle notification payloads
- Navigate to relevant screens on tap
Offline Support
- Cache wallet balance locally
- Queue transactions when offline
- Sync on reconnection
- Show sync status to user
UI Components
- Design custom wallet widget
- Create offer status badges
- Build transaction list items
- Implement pull-to-refresh
Represents user's financial account:
Fields:
_id: Unique identifieruser: Reference to user documentbalance: Available fundsescrowBalance: Funds held in escrowcurrency: Currency code (default: "USD")isActive: Account active statusisFrozen: Account frozen status (prevents transactions)totalEarnings: Lifetime earningstotalSpent: Lifetime spendingtotalWithdrawals: Lifetime withdrawalscreatedAt: Account creation timestampupdatedAt: Last update timestamp
Represents job offer between customer and contractor:
Fields:
_id: Unique identifierjob: Reference to job documentcustomer: Reference to customer usercontractor: Reference to contractor userapplication: Reference to application documentamount: Job budget amountplatformFee: 5% platform feeserviceFee: 20% service feecontractorPayout: 80% contractor paymenttotalCharge: Total amount charged to customertimeline: Expected completion timelinedescription: Work descriptionstatus: Current status (pending, accepted, rejected, cancelled, completed, expired)acceptedAt: Acceptance timestamprejectedAt: Rejection timestampcancelledAt: Cancellation timestampcompletedAt: Completion timestampexpiresAt: Expiration timestamp (7 days from creation)rejectionReason: Reason for rejectioncancellationReason: Reason for cancellationcreatedAt: Creation timestampupdatedAt: Last update timestamp
Records all financial movements:
Fields:
_id: Unique identifiertype: Transaction typedeposit: Money added to walletwithdrawal: Money withdrawnescrow_hold: Money moved to escrowescrow_release: Money released from escrowplatform_fee: Platform fee paymentservice_fee: Service fee paymentcontractor_payout: Payment to contractorrefund: Refund to customer
amount: Transaction amountfrom: Sender user (populated)to: Receiver user (populated)offer: Reference to related offerjob: Reference to related jobstatus: Transaction status (pending, completed, failed)description: Transaction descriptionfailureReason: Reason for failurecompletedAt: Completion timestampcreatedAt: Creation timestampupdatedAt: Last update timestamp
Extended with payment fields:
Payment-Related Fields:
contractorId: Assigned contractor referenceofferId: Accepted offer referencestatus: Job status (open, assigned, in_progress, completed, cancelled)assignedAt: Assignment timestampcompletedAt: Completion timestampcancelledAt: Cancellation timestampcancellationReason: Reason for cancellation
Allowed Actions:
- Deposit money into wallet
- Send offers to contractors
- Mark jobs as complete
- Cancel jobs before completion
- View transaction history
- View wallet balance
Restrictions:
- Cannot withdraw money
- Cannot accept their own offers
- Cannot update job status to "in_progress"
Allowed Actions:
- Accept or reject offers
- Update job status to "in_progress"
- Withdraw earnings from wallet
- View transaction history
- View wallet balance
Restrictions:
- Cannot send offers
- Cannot mark jobs as complete
- Cannot cancel jobs (only customer/admin can)
Allowed Actions:
- Receive platform fees and service fees
- Cancel jobs on behalf of users
- View all transactions
- Freeze wallets if needed
- Override system restrictions
Automatic Functions:
- Admin user auto-created on first run
- Admin wallet auto-created
- Commission transfers automatic
- No manual intervention required
| Code | Status | Meaning |
|---|---|---|
| 400 | Bad Request | Invalid input or validation failed |
| 401 | Unauthorized | Missing or invalid authentication token |
| 403 | Forbidden | Insufficient permissions for action |
| 404 | Not Found | Requested resource doesn't exist |
| 500 | Server Error | Internal server error occurred |
All errors follow consistent structure:
{
"status": 400,
"message": "Human-readable error description",
"data": null,
"errors": [
{
"field": "amount",
"message": "Amount must be at least $10"
}
]
}- Insufficient balance: Not enough available funds
- Wallet not found: User wallet doesn't exist (auto-creates)
- Minimum deposit: Deposit below $10
- Maximum withdrawal: Withdrawal above $10,000
- Wallet frozen: Account locked by admin
- Contractor only: Non-contractors attempting withdrawal
- Offer already exists: One offer per job rule violation
- Job not open: Job already assigned or completed
- Insufficient balance: Not enough for total charge
- Not authorized: User doesn't own resource
- Offer expired: Offer past 7-day expiration
- Invalid status: Offer in wrong status for action
- Job not found: Invalid job ID
- Invalid status transition: Illegal status change
- Cannot cancel completed: Completed jobs immutable
- No contractor assigned: Required contractor missing
- Not in progress: Job must be in progress for completion
JWT Token System
- Access tokens valid for 15 days (development)
- Refresh tokens valid for 30 days
- Tokens include user ID and role
- Validated on every protected endpoint
Role-Based Access Control
- Customer-only endpoints (send offer, complete job, cancel)
- Contractor-only endpoints (accept/reject offer, withdraw)
- Admin endpoints (override actions, freeze wallets)
- Automatic role verification via middleware
Zod Schema Validation
- All inputs validated before processing
- Type checking and constraints enforced
- Custom error messages for clarity
- Prevents injection attacks
Amount Validation
- Positive numbers only
- Minimum and maximum limits
- Decimal precision controlled
- Currency format validated
String Validation
- Length constraints enforced
- Character set restrictions
- SQL injection prevention
- XSS protection
Balance Verification
- Pre-transaction balance check
- Atomic balance updates
- Race condition prevention
- Rollback on failures
Escrow Protection
- Funds held securely until completion
- Cannot be accessed during hold
- Automatic release on completion/cancellation
- Separate from available balance
Audit Trail
- Every transaction recorded
- Immutable transaction history
- Sender and receiver tracked
- Timestamps for all events
Freeze Functionality
- Admin can freeze suspicious wallets
- Prevents all transactions when frozen
- User notified of freeze
- Requires admin intervention to unfreeze
Withdrawal Limits
- Minimum: $10
- Maximum: $10,000 per transaction
- Prevents money laundering
- Configurable per system needs
Prerequisites
- Create test customer account
- Create test contractor account
- Obtain authentication tokens
- Set up API testing tool (Postman/Insomnia)
Test Scenario 1: Happy Path
-
Customer deposits $200
- Verify wallet balance updated
- Check transaction created
-
Customer posts job
- Verify job created with "open" status
-
Contractor applies to job
- Verify application created
-
Customer sends $100 offer
- Verify wallet deducted $105
- Check escrow balance increased
- Confirm offer created with pending status
-
Contractor accepts offer
- Verify job status "assigned"
- Check platform fee ($5) transferred to admin
- Confirm other applications rejected
-
Contractor updates to "in_progress"
- Verify job status updated
-
Customer marks complete
- Verify service fee ($20) to admin
- Check contractor receives $80
- Confirm job status "completed"
-
Contractor withdraws $50
- Verify balance decreased
- Check transaction created
Test Scenario 2: Offer Rejection
1-4. Same as Happy Path
-
Contractor rejects offer
- Verify full refund ($105) to customer
- Check application status reset
- Confirm notification sent
-
Customer sends new offer
- Verify process repeats
Test Scenario 3: Job Cancellation
1-6. Same as Happy Path
- Customer cancels job
- Verify refund processed
- Check escrow released
- Confirm job status "cancelled"
Test Scenario 4: Insufficient Balance
- Customer deposits $50
2-3. Same as Happy Path
- Customer attempts $100 offer
- Verify error: "Insufficient balance"
- Check wallet unchanged
- Confirm no offer created
Test Scenario 5: Offer Expiration
1-4. Same as Happy Path
- Wait for automated job to run (or manually trigger)
- Verify offer status "expired"
- Check full refund to customer
- Confirm application reset
Success Responses
- Status code 200 or 201
- Consistent response structure
- All required fields present
- Correct data types
Error Responses
- Appropriate status codes
- Clear error messages
- Error details when applicable
- Consistent format
Response Times
- Wallet operations: < 500ms
- Offer operations: < 1000ms
- Transaction queries: < 2000ms
- Job operations: < 1000ms
Concurrency
- Multiple simultaneous offers
- Parallel wallet operations
- Concurrent job updates
- Race condition handling
Required Variables
ADMIN_USER_ID=<optional_admin_id>
DATABASE_URL=<mongodb_connection_string>
JWT_SECRET=<secret_key>
Optional Variables
STRIPE_SECRET_KEY=<stripe_key>
STRIPE_WEBHOOK_SECRET=<webhook_secret>
FCM_SERVER_KEY=<firebase_key>
Initial Setup
- No manual migrations required
- Admin user auto-creates on first run
- Admin wallet auto-creates automatically
- Indexes created automatically
Data Persistence
- MongoDB for all data storage
- Transaction logs immutable
- Wallet balances atomic
- Job states consistent
Automated Jobs
- Offer expiration runs hourly
- Starts automatically on server launch
- Logs all processed offers
- Error handling per offer
Socket.IO Server
- Real-time notification support
- Automatic reconnection
- Room-based messaging
- Event broadcasting
System Health
- Database connectivity
- Admin user existence
- Admin wallet existence
- Automated job status
Monitoring Points
- Failed transactions
- Stuck offers
- Frozen wallets
- Error rates
API Documentation
- Swagger UI:
/swagger - Scalar UI:
/scaler - JSON Specification:
/api-docs.json
Implementation Guides
doc/payment/IMPLEMENTATION_GUIDE.md: Complete backend guidedoc/payment/API_DESIGN.md: API architecturedoc/payment/DATABASE_SCHEMA.md: Database designdoc/payment/REVISED_FLOW.md: Flow diagrams
Frontend Resources
doc/payment/IMPLEMENTATION/FRONTEND_API_DOCUMENTATION.md: Complete API referencedoc/payment/IMPLEMENTATION/QUICK_START_GUIDE.md: Quick referencedoc/payment/IMPLEMENTATION/POSTMAN_COLLECTION_GUIDE.md: Testing guide
Contact Channels
- Backend Team: [email protected]
- Technical Support: [email protected]
- Emergency Issues: [email protected]
Response Times
- Critical Issues: 1 hour
- High Priority: 4 hours
- Medium Priority: 24 hours
- Low Priority: 3 business days
Source Code
- Admin Service:
src/common/service/admin.service.ts - Wallet Services:
src/api/wallet/services/ - Offer Services:
src/api/job-request/services/ - Job Services:
src/api/job/services/ - Automated Jobs:
src/jobs/
Configuration
- Payment Config:
src/config/payment-config.ts - Validation Schemas:
src/api/*/validation.ts - Routes:
src/api/*/routes.ts
Initial Release
- ✅ Wallet management system
- ✅ Offer creation and management
- ✅ Job payment processing
- ✅ Withdrawal functionality
- ✅ Automated offer expiration
- ✅ Transaction history
- ✅ Real-time notifications
- ✅ Admin service integration
- ✅ Complete API documentation
- ✅ Production-ready deployment
System Status
- Build: ✅ Passing
- Tests: ✅ Verified
- Documentation: ✅ Complete
- Security: ✅ Implemented
- Performance: ✅ Optimized
Customer Pays = Job Budget × 1.05
Platform Fee = Job Budget × 0.05 (on acceptance)
Service Fee = Job Budget × 0.20 (on completion)
Contractor Gets = Job Budget × 0.80 (on completion)
Admin Total = Job Budget × 0.25 (combined)
Job: open → assigned → in_progress → completed
Offer: pending → accepted → completed
Application: pending → accepted/rejected
Minimum Deposit: $10
Minimum Withdrawal: $10
Maximum Withdrawal: $10,000
Offer Expiration: 7 days
Token Validity: 15 days (access), 30 days (refresh)
- ✅ All core features implemented
- ✅ Authentication and authorization
- ✅ Input validation and sanitization
- ✅ Error handling and logging
- ✅ Transaction security
- ✅ Automated processes
- ✅ API documentation
- ✅ Testing completed
- ✅ Deployment guidelines
- ✅ Support channels established
System Status: ✅ Production Ready
Documentation Version: 1.0.0
Last Verified: November 13, 2025
For detailed technical implementation, refer to the comprehensive documentation in the doc/payment/ directory.