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>
181 lines
6.6 KiB
Markdown
181 lines
6.6 KiB
Markdown
# 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).
|