Initial commit — Performance West telecom compliance platform
Includes: API (Express/TypeScript), Astro site, Python workers, document generators, FCC compliance tools, Canada CRTC formation, Ansible infrastructure, and deployment scripts. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
commit
f8cd37ac8c
1823 changed files with 145167 additions and 0 deletions
181
docs/relay-integration.md
Normal file
181
docs/relay-integration.md
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
# Relay Financial Integration
|
||||
|
||||
**Last updated:** 2026-03-19
|
||||
|
||||
## Overview
|
||||
|
||||
Relay (relayfi.com) is our business banking platform. We use a dedicated
|
||||
Relay virtual debit card to pay state filing fees during automated business
|
||||
formation. Relay does NOT have a public developer API, so integration is
|
||||
via encrypted card storage + Playwright automation + Plaid for read-only
|
||||
transaction data.
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
ERPNext (Sensitive ID) Playwright State Portal
|
||||
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
|
||||
│ Relay card details│────►│ Formation worker │────►│ Payment form │
|
||||
│ (AES encrypted) │ │ enters card into │ │ Card charged │
|
||||
│ card_number │ │ state portal form │ │ Filing confirmed │
|
||||
│ exp_month/year │ └──────────────────┘ └──────────────────┘
|
||||
│ cvv │ │
|
||||
│ billing_zip │ ▼
|
||||
└──────────────────┘ ┌──────────────────┐
|
||||
│ filing_payments │
|
||||
│ table (PostgreSQL)│
|
||||
│ card_last4, amount│
|
||||
│ confirmation # │
|
||||
└──────────────────┘
|
||||
│
|
||||
▼ (reconcile)
|
||||
┌──────────────────┐
|
||||
│ Relay dashboard │
|
||||
│ or Plaid read-only│
|
||||
│ transaction match │
|
||||
└──────────────────┘
|
||||
```
|
||||
|
||||
## Card Details Storage
|
||||
|
||||
Card details are stored in ERPNext's **Sensitive ID** DocType using the
|
||||
Frappe Password fieldtype, which provides AES encryption at rest.
|
||||
|
||||
### Setup (One-time)
|
||||
|
||||
1. Log into ERPNext at crm.performancewest.net
|
||||
2. Navigate to Sensitive ID → New
|
||||
3. Set:
|
||||
- **Name:** `relay-filing-card`
|
||||
- **ID Type:** `DEBIT_CARD`
|
||||
- **Encrypted Value:** (paste JSON below)
|
||||
|
||||
```json
|
||||
{
|
||||
"number": "4000123456789012",
|
||||
"exp_month": "12",
|
||||
"exp_year": "28",
|
||||
"cvv": "123",
|
||||
"name": "Performance West Inc",
|
||||
"zip": "82001"
|
||||
}
|
||||
```
|
||||
|
||||
4. Save — the value is encrypted by Frappe's Password field
|
||||
|
||||
### Runtime Flow
|
||||
|
||||
1. Job server receives a `file_entity` job
|
||||
2. `relay_integration.populate_order_payment()` loads card from ERPNext
|
||||
3. Card details are held in memory only (never logged, never written to disk)
|
||||
4. Playwright enters card details into state portal payment form
|
||||
5. After filing, card details are cleared from memory
|
||||
6. `record_filing_payment()` logs the payment (card_last4 only) for reconciliation
|
||||
|
||||
## Payment Reconciliation
|
||||
|
||||
After each filing, a record is created in the `filing_payments` table:
|
||||
|
||||
| Field | Value |
|
||||
|-------|-------|
|
||||
| formation_order_id | Links to the order |
|
||||
| state_code | Which state was paid |
|
||||
| amount_cents | How much was charged |
|
||||
| card_last4 | Last 4 digits for matching |
|
||||
| portal_confirmation | State portal confirmation # |
|
||||
| reconciled | FALSE until matched |
|
||||
|
||||
### Matching Relay Transactions
|
||||
|
||||
**Option A — Manual (current):**
|
||||
Export Relay transactions as CSV, compare against `filing_payments` table.
|
||||
|
||||
**Option B — Plaid (future):**
|
||||
Connect Relay to Plaid, then connect Plaid to ERPNext via the community
|
||||
Plaid integration. This gives read-only access to Relay transactions for
|
||||
automatic reconciliation.
|
||||
|
||||
**Option C — QuickBooks bridge (future):**
|
||||
Relay → QuickBooks Online sync → ERPNext QBO integration. Transactions
|
||||
flow: Relay → QBO → ERPNext → auto-match against filing_payments.
|
||||
|
||||
## Commission Payouts via ACH
|
||||
|
||||
Sales agent commissions are tracked in the `commission_ledger` table in
|
||||
PostgreSQL and reconciled with ERPNext.
|
||||
|
||||
### Agent Setup
|
||||
|
||||
Sales agents are created via `POST /api/v1/admin/agents`, which:
|
||||
1. Creates the agent record with an auto-generated `REF-XXXXX` referral code
|
||||
2. Creates a linked discount code (5% off service fee) tied to the agent
|
||||
3. Agent shares their referral link or discount code with prospects
|
||||
|
||||
### Commission Amounts
|
||||
|
||||
Commissions are configurable per service type:
|
||||
|
||||
| Service | Commission |
|
||||
|---------|-----------|
|
||||
| Canada CRTC registration | $300 |
|
||||
| Business formations | $50 |
|
||||
| Compliance services | 10% of service fee |
|
||||
| Service bundles | $100 |
|
||||
|
||||
### Commission Lifecycle
|
||||
|
||||
```
|
||||
pending → eligible → approved → processing → paid
|
||||
```
|
||||
|
||||
1. **Pending:** Commission record created when referred order is placed
|
||||
2. **Eligible:** 14-day holdback after order delivery has passed
|
||||
3. **Approved:** Admin reviews and approves in ERPNext
|
||||
4. **Processing:** ACH payment initiated via Relay dashboard
|
||||
5. **Paid:** ACH confirmed, `commission_ledger` updated with `paid_at` and `relay_transaction_id`
|
||||
|
||||
### Automation
|
||||
|
||||
- `commission_worker.py` runs as a daily cron job
|
||||
- Scans `commission_ledger` for commissions past the 14-day holdback
|
||||
- Transitions qualifying records from `pending` → `eligible`
|
||||
- Sends admin notification in ERPNext for batch approval
|
||||
- After admin approval, payment is made via Relay ACH (manual — no Relay API)
|
||||
|
||||
### Future: ACH API
|
||||
|
||||
If Relay adds API support (or we switch to a banking-as-a-service provider
|
||||
like Mercury, Brex, or Column), we can automate ACH payouts. The
|
||||
`commission_ledger` table is designed for this — the `status` field
|
||||
tracks the full lifecycle from pending through paid.
|
||||
|
||||
## Virtual Card Security
|
||||
|
||||
- Card only funded to the amount needed for the next filing
|
||||
- Separate Relay checking account dedicated to filing fees
|
||||
- Card number stored AES-encrypted in ERPNext (Frappe Password field)
|
||||
- Card details only in memory during Playwright automation
|
||||
- Never logged, never written to disk, never in screenshots
|
||||
- `filing_payments` table stores only last4 digits
|
||||
- If card is compromised, max exposure = current balance (minimal)
|
||||
|
||||
## Relay Account Structure
|
||||
|
||||
Recommended Relay account organization (Profit First method):
|
||||
|
||||
| Account | Purpose |
|
||||
|---------|---------|
|
||||
| **Operating** | Main revenue account |
|
||||
| **Filing Fees** | Dedicated to state filing fee payments (virtual card attached) |
|
||||
| **Profit** | Retained earnings |
|
||||
| **Tax** | Tax reserves |
|
||||
| **Commissions** | Referral partner payouts (ACH from here) |
|
||||
| **Owner Pay** | Owner distributions |
|
||||
|
||||
## Environment Variables
|
||||
|
||||
```
|
||||
RELAY_FILING_CARD_ID=relay-filing-card # ERPNext Sensitive ID name
|
||||
```
|
||||
|
||||
No Relay API credentials needed (there is no API).
|
||||
Loading…
Add table
Add a link
Reference in a new issue