new-site/docs/billing.md
justin f8cd37ac8c 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>
2026-04-27 06:54:22 -05:00

16 KiB

Billing & Payments Architecture

Last updated: 2026-04-05

Principle: ERPNext Owns All Billing

All payment processing, invoicing, and financial record-keeping flows through ERPNext. Our Express API and website are the storefront — ERPNext is the back office. Payment gateways are Frappe apps installed inside ERPNext.

Payment Methods

Method Gateway Provider App Integration
Credit/Debit (Visa, MC, Amex) + Apple Pay + Google Pay Adyen frappe_adyen ERPNext Payment Request → Adyen Sessions API v71
ACH Direct Debit Adyen frappe_adyen ERPNext Payment Request → Adyen ACH
Klarna (Pay in 4) Adyen frappe_adyen ERPNext Payment Request → Adyen Klarna
Cash App Pay Adyen frappe_adyen ERPNext Payment Request → Adyen CashApp
Amazon Pay Adyen frappe_adyen ERPNext Payment Request → Adyen AmazonPay
Cryptocurrency (BTC/ETH/USDC/USDT/MATIC/TRX/BNB/LTC/DOGE) SHKeeper frappe_crypto ERPNext Payment Request → SHKeeper API (k3s)
Stripe Identity Stripe Direct (API only) Identity verification for CRTC orders — NOT used for payments

Note: Adyen account approval is pending. SHKeeper is deployed and running in k3s.

Payment Surcharges

We pass processor costs through as surcharges on select payment methods:

Method Customer Surcharge Our Gateway Cost Notes
ACH Direct Debit 0% $0.40 flat Recommended — lowest cost
Credit/Debit Card 3% ~2.2% (IC++) Visa/MC/Amex + Apple Pay + Google Pay
Klarna 5% 4.29% + $0.30 Adyen Klarna rate
Cash App Pay 3% 2.90% + $0.30
Amazon Pay 3% ~2.9-3.4% Negotiated rate
Cryptocurrency 0% $0 Self-hosted SHKeeper — zero fees

Surcharge injection is handled by performancewest_erpnext via a Payment Request.before_insert hook that reads the surcharge rate from the payment gateway and adds it to the invoice total.

Legal notes:

  • Surcharges are prohibited in CT, MA, and PR — residents of these jurisdictions are not charged surcharges.
  • Surcharges apply to service fees only, not state filing fees.

SHKeeper (Crypto Payments)

Self-hosted in k3s (Kubernetes) at pay.performancewest.net. Zero processing fees — fully non-custodial. Supports BTC, ETH, USDC, USDT, MATIC, TRX, BNB, LTC, DOGE, and any ERC-20/TRC-20/BEP-20 token.

Installed via Helm chart vsys-host/shkeeper. k3s runs with --docker --disable=traefik to avoid port conflicts with host nginx.

Customer chooses crypto payment
  → ERPNext creates Payment Request (gateway: Crypto)
  → frappe_crypto calls SHKeeper POST /api/v1/<crypto>/payment_request
  → Customer sees wallet address + QR code on crypto_checkout page
  → SHKeeper webhook fires (must return HTTP 202, not 200)
  → frappe_crypto.api.crypto_webhook verifies X-Shkeeper-Api-Key header
  → ERPNext marks Payment Request as Paid
  → ERPNext workflow webhook → Express API → Workers

Adyen (Card/ACH/Klarna/CashApp/AmazonPay)

Pending Adyen account approval. When live, 5 gateway instances will be configured:

Instance Payment Methods Adyen Type
Card Visa, MC, Amex, Apple Pay, Google Pay scheme, applepay, googlepay
ACH US bank account direct debit ach
Klarna Pay in 4 installments klarna
CashApp Cash App Pay cashapp
AmazonPay Amazon Pay amazonpay

frappe_adyen uses Adyen Sessions API v71 with HMAC-SHA256 webhook verification using Adyen's field concatenation algorithm. 74 unit tests passing.

Payment Flow

┌──────────┐    ┌──────────┐    ┌──────────────┐    ┌──────────────┐
│  Website  │───►│ Express  │───►│   ERPNext    │───►│    Adyen     │
│  (Astro)  │    │   API    │    │              │    │  (Card/ACH/  │
│           │    │          │    │ Sales Invoice│    │  Klarna/     │
│ Customer  │    │ Validate │    │ Payment Req  │    │  CashApp/    │
│ fills     │    │ + create │    │              │    │  AmazonPay)  │
│ order     │    │ in ERPNext│   │              │    ├──────────────┤
└──────────┘    └──────────┘    └──────┬───────┘    │  SHKeeper    │
                                       │            │  (Crypto)    │
                              ┌────────▼────────┐   └──────────────┘
                              │ Customer is     │
                              │ redirected to   │
                              │ payment page    │
                              │                 │
                              │ Adyen checkout  │
                              │ or crypto QR    │
                              └────────┬────────┘
                                       │
                              ┌────────▼────────┐
                              │ Gateway webhook │
                              │ → ERPNext marks │
                              │   Invoice Paid  │
                              │                 │
                              │ ERPNext webhook │
                              │ → Express API   │
                              │ → Workers       │
                              └─────────────────┘

Invoice Types

Formation Orders

Sales Invoice:
  Customer: Sarah Chen
  Items:
    - LLC Formation (Basic): $179.00
    - State Filing Fee (Wyoming): $100.00
    - EIN Obtainment: $49.00
    - Operating Agreement: $99.00
  Discount: -$37.25 (LAUNCH25 — 25% off service fee)
  Total: $360.75
  Payment Gateway: Adyen-Card
  Status: Paid

Compliance Services

Sales Invoice:
  Customer: Marcus Johnson
  Items:
    - FLSA Wage & Hour Audit (up to 50 employees): $1,499.00
  Total: $1,499.00
  Payment Gateway: Adyen-ACH
  Status: Unpaid → Payment Request Sent

Recurring Services (Subscriptions)

ERPNext Subscription DocType handles:

  • Registered Agent: $99/year per state (Wyoming: $49/year)
  • Annual Report Filing: $99/year per state
  • Canada CRTC Annual Maintenance: $349/year
  • US Formation Maintenance Bundle: $179/year (annual report + RA renewal)
  • CA Formation Maintenance Bundle: $179/year (annual return + AMB/RA renewal)

Subscriptions auto-generate invoices. Payment collected via Adyen (saved payment method) or manual payment link.

Formation Maintenance Bundles

Bundle Price Includes Savings
US Formation Maintenance $179/yr Annual Report filing ($99) + RA renewal ($99) $19/yr vs separate
CA Formation Maintenance $179/yr Annual Return filing ($99) + compliance monitoring ($99). AMB mailbox renewal billed separately at cost. N/A
CRTC Maintenance (existing) $349/yr All of CA maintenance + CRTC + CCTS + domain/email + DID N/A

Formation maintenance bundles are offered to Complete tier customers. Basic tier customers can purchase individual services (Annual Report $99/yr, RA $99/yr) separately.

Canadian Formation Pricing (Standalone — Not CRTC)

Item Price Notes
Canadian Formation C$449 Includes: incorporation, org minutes, corporate binder, compliance calendar. AMB mailbox billed separately.
Government fees Passed through BC ~C$350, ON ~C$360 (BoC rate + 10% buffer)
Add-on: CRA BN $49 Business Number registration with CRA
Add-on: Named company +gov fee Name reservation (province-specific)
Free DID Included With formation + RA renewal (stub — not yet active)

Service Bundles

Customers receive 20% off when purchasing all services in a category (e.g., all formation add-ons, all compliance services for a given tier).

  • Discount applies to service fees only — state filing fees and registered agent fees included in bundles are not discounted.
  • RA fees are NOT discountable in bundles, but YES with discount codes.
  • Bundle discount is calculated in ERPNext via Pricing Rules and applied automatically when all qualifying items are in the Sales Order.

Canada CRTC Package Pricing

Item Price
CRTC Telecom Registration (one-time) $3,899 USD
Annual Maintenance & Compliance $349/yr
Consulting (regulatory, technical) $75/hr
Accounting Support 3 hrs free included, then $75/hr

The CRTC package is a single Sales Order in ERPNext with all line items. Annual maintenance is handled via ERPNext Subscription (auto-renew via Adyen saved payment method).

Payment flexibility: ~$975/mo x 4 via Klarna Pay in 4 (5% surcharge applies).

Sales Agent Commissions

Sales agents earn commissions on referred sales:

Detail Value
Canada CRTC sale $300 per sale
Formation sale $50 per sale
Bundle sale $100 per sale
Payment timing 14 days after order delivery
Payment method Relay ACH transfer
Tracking ERPNext Commission Ledger DocType + PostgreSQL backup

Commission workflow:

  1. Customer purchases using agent's REF-XXXXX referral code
  2. Client gets 5% off service fee
  3. Order is fulfilled and delivered
  4. 14-day holdback period begins
  5. After holdback, commission becomes eligible
  6. Admin approves and pays via Relay ACH
  7. Commission Ledger record updated with payment details

Refunds

Refunds flow through ERPNext's Credit Note system:

  1. Admin creates a Credit Note against the original Sales Invoice
  2. ERPNext processes the refund via the original gateway (Adyen automatic refund, or manual ACH via Relay)
  3. Credit Note tracks: amount, reason, linked invoice, approval
  4. Our refunds table in PostgreSQL is a backup/audit — ERPNext is the source of truth

For state filing fees specifically:

  • State fee refunds require contacting the state directly (most states don't refund filing fees)
  • Our service fee is always refundable if the failure was our fault
  • ERPNext tracks whether state fee is recoverable separately

Express API Changes

Our API routes no longer handle payment directly:

Before After
API collects payment info API creates Sales Invoice + Payment Request in ERPNext
API charges gateway ERPNext gateway (Adyen/SHKeeper) handles payment
API stores payment records ERPNext manages invoices
API handles refunds ERPNext issues Credit Notes

The checkout flow:

  1. Customer fills order on Astro site → submits to Express API
  2. Express API creates ERPNext Sales Invoice + Payment Request
  3. Customer is redirected to ERPNext payment page (Adyen checkout or crypto QR)
  4. Payment gateway webhook → ERPNext marks as Paid
  5. ERPNext workflow webhook → Express API → Workers start fulfillment

Old providers/ directory (stripe.ts, btcpay.ts, adyen.ts) and webhooks-stripe.ts have been deleted.

ERPNext Setup Status

Completed:

  • Install Payments app (bench get-app payments)
  • Install frappe_crypto (SHKeeper gateway) — v1.0.0
  • Install frappe_adyen (Adyen gateway) — v1.0.0
  • Install performancewest_erpnext (surcharge hooks, identity gate) — v1.0.0
  • Create 16 Item records for all services (formation, compliance, add-ons, CRTC)
  • Update Subscription Plans to new pricing (RA $99/yr ($49 WY), Annual Report $99/yr, CRTC Maintenance $349/yr)
  • Import 7 custom DocTypes
  • Import 3 workflows (Formation, CRTC, Renewal)
  • Configure custom fields on Sales Order, Sales Invoice, Payment Request

Remaining:

  • Configure Crypto Payment Settings in ERPNext UI (point to https://pay.performancewest.net with SHKeeper API key)
  • Create Payment Gateway Account for Crypto-Crypto
  • Configure 5 Adyen Settings instances when account is approved
  • Create Payment Gateway Accounts for each Adyen instance
  • Configure email templates for invoice/payment notifications
  • Test end-to-end payment flows

Subscription Management

ERPNext Subscription handles recurring billing:

Service Frequency Auto-Renew
Registered Agent Annual Yes (Adyen saved payment method)
Annual Report Filing Annual Yes (Adyen saved payment method)
CRTC Annual Maintenance Annual Yes (Adyen saved payment method)

Subscription lifecycle:

  1. Customer purchases RA service during formation
  2. ERPNext creates Subscription (start date = formation date)
  3. 11 months later: ERPNext sends renewal reminder email
  4. On anniversary: ERPNext auto-generates invoice + Payment Request
  5. Adyen charges saved payment method (or customer pays via link)
  6. If payment fails: ERPNext sends dunning emails
  7. After grace period: service paused, customer notified

Compliance Calendar Renewal Billing

The renewal_worker.py (daily cron at 7 AM) manages billing for compliance calendar entries. This is separate from ERPNext Subscriptions — it handles the 17 per-carrier compliance obligations that have varying due dates and amounts.

Lifecycle

Upcoming → Due Soon (30 days out) → Invoice Sent → Paid → Completed → re-calendar next year
  1. Upcoming: Entry exists with future due date
  2. Due Soon: 30 days before deadline — renewal worker sends reminder email
  3. Invoice Sent: Worker creates ERPNext Sales Invoice for billable items
  4. Paid: ERPNext webhook fires on invoice payment → handle_renewal_payment job
  5. Completed: Entry marked done, admin ToDo created for the actual filing/action
  6. Re-calendar: New entry auto-created for next period (annual/quarterly/monthly)

Billable vs Non-Billable Entries

Type Billable Amount ERPNext Item
CRTC Annual Maintenance Yes $349 USD CRTC-MAINT-ANNUAL
Mailbox Renewal Yes ~$199 USD MAILBOX-RENEWAL
BC Annual Report Yes ~$50 CAD BC-ANNUAL-REPORT
Domain + Hosting Renewal Yes ~$25 USD DOMAIN-RENEWAL-CA
DID Renewal Yes ~$10 USD (included in CRTC maintenance)
CCTS Renewal No $0
T2 Tax Return No $0 (client's accountant)
GST/HST Return No $0 (client's accountant)
CRTC Registration Update No $0
ATS Surveys No $0 (we prepare, client files)

ERPNext Items Needed for Renewal Invoicing

These ERPNext Items must be created for the renewal worker to generate invoices:

Item Code Item Name Rate (USD)
CRTC-MAINT-ANNUAL CRTC Annual Maintenance & Compliance $349
MAILBOX-RENEWAL Vancouver Mailbox Renewal (Annual) $199
BC-ANNUAL-REPORT BC Annual Report Filing $50
DOMAIN-RENEWAL-CA .ca Domain + Hosting + Email Renewal $25
COMPLIANCE-OTHER Compliance Service (Miscellaneous) Variable

Compliance Calendar DocType Fields

The Compliance Calendar ERPNext DocType includes these billing-related fields:

Field Type Purpose
amount_usd Currency Billable amount in USD
amount_cad Currency Billable amount in CAD (for Canadian gov fees)
invoice Link (Sales Invoice) ERPNext invoice reference
recurring Check Whether entry recurs annually
recurrence_period Select Annual / Quarterly / Monthly
renewal_of Link (Compliance Calendar) Previous entry this renews
compliance_type Select Regulatory / Tax / Survey
entity_name Data Carrier/company name
order_reference Link (Sales Order) Original CRTC order
reminder_date Date When to send reminder (30 days before due)

Environment Variables

# ERPNext API (set in Express API .env)
ERPNEXT_URL=https://crm.performancewest.net
ERPNEXT_API_KEY=<key>
ERPNEXT_API_SECRET=<secret>

# SHKeeper (set in server .env)
SHKEEPER_API_KEY=<key>              # NEEDS TO BE SET
SHKEEPER_URL=https://pay.performancewest.net

# Stripe Identity only (NOT for payments)
STRIPE_IDENTITY_WEBHOOK_SECRET=<secret>   # NEEDS TO BE SET

# SMTP
SMTP_PASS=<password>                # NEEDS TO BE SET

# Customer Portal
CUSTOMER_JWT_SECRET=<secret>        # NEEDS TO BE GENERATED: openssl rand -base64 32

All Adyen keys are configured inside ERPNext's Adyen Settings DocType, not in the Express API .env.