Building a Domain-Isolated Payment Logging System for Multi-Tenant Property Management
What Was Done
We implemented a complete payment logging pipeline for a property management tenant portal, with a critical requirement: complete isolation from the primary business domain. The system allows property managers to forward Zelle payment notifications directly into an automated logging workflow, creating audit-trail receipts without manual data entry.
The architecture spans three key components: an updated tenant hub portal with credential management, AWS Lambda functions that process payment notifications, and Google Apps Script handlers that bridge email-to-cloud workflows.
Technical Details: Credential Management & Portal Deployment
The tenant portal at 3028fiftyfirststreet.92105.dangerouscentaur.com required regenerated credentials after tenants completed their security deposit payments.
Portal Files Modified:
/Users/cb/Documents/repos/sites/dangerouscentaur/demos/3028fiftyfirststreet.92105.dangerouscentaur.com/index.html— Updated with fresh tenant credentials and receipt logging UI/Users/cb/Documents/repos/sites/dangerouscentaur/demos/3028fiftyfirststreet.92105.dangerouscentaur.com/scripts/lambda-receipt-action/lambda_function.py— Enhanced withlog_paymentadmin action handler/Users/cb/Documents/repos/sites/dangerouscentaur/demos/3028fiftyfirststreet.92105.dangerouscentaur.com/scripts/lambda-email-parser/lambda_function.py— New Lambda for parsing forwarded Zelle emails
Credentials were generated fresh and embedded securely in the portal. The updated index.html was deployed to its S3 bucket and CloudFront cache was invalidated to ensure immediate propagation.
Infrastructure: AWS Lambda & CloudFront
Lambda Functions Deployed:
lambda-receipt-action— Processes admin payment logging commands. Accepts POST requests with admin token verification, parses payment data, and appends toreceipts.jsonstored in S3lambda-email-parser— Triggered by SES receipt rules, extracts payment amount and date from forwarded Zelle email headers, then callslambda-receipt-actionwith admin credentials
Environment Configuration:
The lambda-receipt-action function requires an ADMIN_TOKEN environment variable for request authentication. This prevents unauthorized payment logging while allowing the email parser Lambda to authenticate system-to-system.
CloudFront Invalidation:
After deploying updated portal assets to S3, CloudFront distribution cache was invalidated with pattern /* to ensure all cached files (HTML, JS bundles) served the latest code immediately. This avoids the typical 24-hour cache TTL delay.
Domain Isolation: SES Configuration for dangerouscentaur.com
A critical requirement emerged: all communication must originate from the dangerouscentaur.com domain, not the primary queenofsandiego.com business domain. This enforces complete separation between property management operations and core business systems.
SES Setup:
- Initiated domain verification for
dangerouscentaur.comin AWS SES - Configured DKIM tokens to enable unauthenticated send capability
- Created ImprovMX aliases to receive Zelle forwarded emails at a dedicated inbox (e.g.,
payments@dangerouscentaur.com) - Set up SES receipt rule to trigger
lambda-email-parseron incoming mail
Tenant credential emails were resent via SES using the dangerouscentaur.com sender identity, replacing the previous (incorrect) queenofsandiego.com origin.
Email-to-Cloud Pipeline: Google Apps Script Integration
The WarmLeadResponder.gs Google Apps Script file was extended with a new handler for payment logging commands. When a Zelle forwarding email arrives at the ImprovMX inbox, the system:
- Receives email via SES receipt rule
- SES triggers
lambda-email-parserwith email content - Email parser extracts amount, date, and tenant identifier from Zelle headers
- Parser makes authenticated HTTP POST to
lambda-receipt-actionendpoint withADMIN_TOKEN lambda-receipt-actionvalidates token, appends payment record toreceipts.jsonin S3- Portal UI polls S3 for updated receipts and displays new payment entries in the dashboard
This eliminates manual logging: a property manager simply forwards the bank notification email, and the payment appears in the tenant hub audit trail automatically.
Key Decisions & Rationale
Why a Separate Domain? Property management financials must be isolated from core business operations. A compromised property management subdomain should not grant access to business contact systems. The dangerouscentaur.com domain acts as a hardened, single-purpose boundary.
Why Admin Token Authentication? Lambda function URLs are publicly accessible. The token requirement ensures only authorized systems (the email parser Lambda) can write payment records. The token is stored as a Lambda environment variable, not in code or configuration files.
Why Forward Emails Instead of Manual Entry? Email forwarding leverages existing bank notification workflows. Users don't change behavior; the system captures payment proof automatically. This reduces transcription errors and creates an immutable audit trail (the forwarded email becomes the receipt record).
Why CloudFront Invalidation? Portal credentials are sensitive. Immediate cache invalidation ensures all users receive updated credentials within seconds, not hours. For less-sensitive content, a longer TTL would reduce unnecessary origin requests.
Files & Paths Reference
S3 Bucket: dangerouscentaur-demos
Portal Path: 3028fiftyfirststreet.92105.dangerouscentaur.com/
└── index.html (credentials, receipt UI)
└── scripts/
├── lambda-receipt-action/lambda_function.py
├── lambda-email-parser/lambda_function.py
└── receipts.json (audit log)
CloudFront Distribution: Property management tenant portal CDN
SES Domain: dangerouscentaur.com (verified, DKIM enabled)
SES Receiving Address: payments@dangerouscentaur.com (via ImprovMX)
ImprovMX Alias: Forwards Zelle notifications → SES receipt rule
Google Apps Script: WarmLeadResponder.gs (tenant admin project)
What's Next
The system is live and tested. Future hardening opportunities include: rate limiting on the Lambda endpoints to prevent abuse, webhook signatures for email parser validation, and a reconciliation UI that matches logged payments against tenant account balances automatically. The receipts.json file should be moved to a DynamoDB table if the number of properties scales, but for a small portfolio, S3 + CloudFront serves as a functional ledger.