Skip to content

Infrastructure Architecture

1. System Overview

Research Relay LLC operates a vertically integrated e-commerce platform for RUO (Research Use Only) research chemicals. The architecture is built around MedusaJS v2 as the central e-commerce engine, with self-hosted Bitcoin payment infrastructure, specialized high-risk ACH processing, and a privacy-conscious communications stack.

All public-facing services sit behind Cloudflare for DNS, CDN, and DDoS protection. The Bitcoin payment rail runs on a dedicated NixOS server (shops-btc-01) using nix-bitcoin for reproducible, security-hardened deployment. Business operations use a lean SaaS stack: Zoho for email and accounting, Mercury for banking, and Koinly for crypto tax tracking.

Key design principles:

  • Self-custody of Bitcoin -- BTCPay Server is self-hosted; no third-party holds funds
  • MedusaJS as single source of truth -- products, orders, customers, inventory, fulfillment
  • Privacy by default -- minimal PII storage, identity separation, Tor-enabled Bitcoin infrastructure
  • Incremental payment rails -- BTC + ACH at launch, card processing added after 3+ months of bank history

2. Component Inventory

Component Technology Hosting Purpose
Storefront Next.js Cloudflare Pages or Vercel Customer-facing website
Backend MedusaJS v2 VPS (TBD) or Railway E-commerce engine, API, admin dashboard
Database PostgreSQL Same VPS or managed Product catalog, orders, customers
BTC Payments BTCPay Server shops-btc-01 (nix-bitcoin) Bitcoin + Lightning payment processing
Lightning CLN + CLBOSS shops-btc-01 Lightning Network node, automated channel management
ACH Payments Paycron SaaS ACH/eCheck bank transfer processing
Card Payments Easy Pay Direct / Durango SaaS Credit/debit card processing (future)
Payment Gateway Authorize.net SaaS Card payment gateway (future)
Sales Tax Avalara or TaxJar SaaS Multi-state sales tax calculation and filing
Email Zoho Workplace SaaS Business email (@research-relay.com)
Phone OpenPhone SaaS Business phone number
Passwords 1Password SaaS (or self-hosted) Credential management, TOTP 2FA
DNS / CDN Cloudflare SaaS DNS, CDN, WAF, DDoS protection
Docs Site MkDocs Material Cloudflare Pages Internal operations documentation
Banking Mercury SaaS Business checking account
Accounting Zoho Books SaaS Bookkeeping, invoicing, sales tax
Crypto Accounting Koinly SaaS BTC transaction tracking, tax reporting
Domain research-relay.com Cloudflare Registrar Primary domain

3. Architecture Diagram

flowchart TB
    subgraph Internet["Public Internet"]
        Customer["Customer Browser"]
        BTC_Network["Bitcoin Network"]
        LN_Network["Lightning Network"]
    end

    subgraph Cloudflare["Cloudflare (DNS + CDN + WAF)"]
        CF_DNS["DNS"]
        CF_CDN["CDN / DDoS Protection"]
    end

    subgraph Frontend["Storefront"]
        NextJS["Next.js Storefront<br/>Cloudflare Pages / Vercel"]
    end

    subgraph MedusaStack["MedusaJS Stack (VPS)"]
        MedusaAPI["MedusaJS v2 API<br/>+ Admin Dashboard"]
        PostgreSQL["PostgreSQL<br/>Database"]
    end

    subgraph BTCStack["Bitcoin Stack (shops-btc-01)"]
        BTCPay["BTCPay Server"]
        CLN["Core Lightning<br/>+ CLBOSS"]
        Bitcoind["Bitcoin Core<br/>(pruned)"]
        Nginx_BTC["nginx (TLS)"]
    end

    subgraph PaymentProviders["Payment Providers (SaaS)"]
        Paycron["Paycron<br/>ACH/eCheck"]
        AuthNet["Authorize.net<br/>Card Gateway (future)"]
    end

    subgraph ExternalServices["External Services"]
        Avalara["Avalara / TaxJar<br/>Sales Tax"]
        Carriers["USPS / UPS / FedEx<br/>Shipping Rates"]
        ZohoMail["Zoho Mail<br/>Transactional Email"]
    end

    subgraph BusinessOps["Business Operations (SaaS)"]
        Mercury["Mercury<br/>Banking"]
        ZohoBooks["Zoho Books<br/>Accounting"]
        Koinly["Koinly<br/>Crypto Accounting"]
    end

    Customer -->|"HTTPS"| CF_CDN
    CF_CDN --> NextJS
    NextJS -->|"REST API"| MedusaAPI
    MedusaAPI --> PostgreSQL

    MedusaAPI -->|"Greenfield API"| BTCPay
    MedusaAPI -->|"ACH API"| Paycron
    MedusaAPI -->|"Card API (future)"| AuthNet
    MedusaAPI -->|"Tax Calculation"| Avalara
    MedusaAPI -->|"Rate Quotes"| Carriers
    MedusaAPI -->|"SMTP"| ZohoMail

    BTCPay -->|"Webhooks"| MedusaAPI
    Paycron -->|"Webhooks"| MedusaAPI

    BTCPay --> CLN
    BTCPay --> Bitcoind
    CLN --> Bitcoind
    Nginx_BTC --> BTCPay

    CLN <-->|"P2P (port 9735)"| LN_Network
    Bitcoind <-->|"P2P (port 8333)"| BTC_Network
    Customer -->|"HTTPS"| Nginx_BTC

    CF_DNS -->|"A record"| Nginx_BTC

    BTCPay -.->|"CSV Export"| Koinly
    MedusaAPI -.->|"Transaction Data"| ZohoBooks
    Mercury -.->|"Bank Feeds"| ZohoBooks

4. DNS Records Plan

All DNS records are managed in Cloudflare. The domain research-relay.com is registered through Cloudflare Registrar.

A / CNAME Records

Record Type Value Proxy Purpose
research-relay.com CNAME Cloudflare Pages / Vercel target Yes Storefront (Next.js)
www.research-relay.com CNAME research-relay.com Yes WWW redirect to apex
api.research-relay.com A VPS IP address Yes MedusaJS backend API
admin.research-relay.com CNAME api.research-relay.com Yes MedusaJS admin dashboard
btcpay.research-relay.com A shops-btc-01 IP address No BTCPay Server (direct, not proxied)1
docs.research-relay.com CNAME Cloudflare Pages target Yes MkDocs internal docs (or internal only)

MX Records (Zoho Mail)

Priority Record Value
10 research-relay.com mx.zoho.com
20 research-relay.com mx2.zoho.com
50 research-relay.com mx3.zoho.com

Email Authentication (SPF, DKIM, DMARC)

Record Type Name Value
SPF TXT research-relay.com v=spf1 include:zohomail.com -all
DKIM TXT zmail._domainkey (Unique key from Zoho admin console)
DMARC TXT _dmarc v=DMARC1; p=quarantine; rua=mailto:admin@research-relay.com

SSL / ACME

Record Type Name Value Purpose
ACME TXT _acme-challenge.btcpay (Auto-managed by Let's Encrypt) TLS cert for BTCPay Server

All Cloudflare-proxied domains get automatic TLS via Cloudflare's edge certificates. The BTCPay Server uses Let's Encrypt directly since it is not proxied through Cloudflare.


5. Data Flow: Order Lifecycle

The complete lifecycle of an order from browse to accounting reconciliation:

5.1 Browse and Cart

1. Customer visits research-relay.com
   --> Cloudflare CDN serves Next.js storefront

2. Customer browses product catalog
   --> Storefront calls MedusaJS API (GET /store/products)
   --> Products include RUO compliance data, COA links, lot info

3. Customer adds items to cart
   --> Storefront calls MedusaJS API (POST /store/carts)
   --> MedusaJS creates cart with line items in PostgreSQL

5.2 Checkout

4. Customer enters shipping information
   --> MedusaJS validates US-only address (50 states + DC)

5. Age verification + RUO acknowledgment
   --> Customer confirms 18+ age requirement
   --> Customer accepts RUO disclaimer (version tracked in compliance module)
   --> Compliance checkout module records attestation

6. Tax calculation
   --> MedusaJS calls Avalara/TaxJar API
   --> Multi-state sales tax calculated based on shipping address
   --> Tax amount added to order total

7. Shipping rate calculation
   --> MedusaJS calls USPS/UPS/FedEx APIs
   --> Real-time calculated rates presented to customer
   --> Free standard shipping if order >= $200
   --> $15 cold-chain surcharge if applicable

5.3 Payment

The customer chooses one of the available payment methods:

BTC / Lightning Path

8a. Customer selects "Pay with Bitcoin"
    --> MedusaJS calls BTCPay Greenfield API to create invoice
    --> BTCPay returns checkout link with BTC address + Lightning invoice
    --> Customer sees QR code, amount in BTC, 15-minute countdown

9a. Customer pays from their wallet
    --> Lightning: instant settlement, InvoiceSettled webhook fires immediately
    --> On-chain: InvoiceProcessing fires (tx in mempool),
        InvoiceSettled fires after 1 confirmation (~10 min)

10a. BTCPay sends webhook to MedusaJS
     --> POST /hooks/payment/btcpay_btcpay
     --> HMAC-SHA256 signature verified
     --> Payment status updated: authorized --> captured

ACH Path

8b. Customer selects "Pay with Bank Transfer (ACH)"
    --> MedusaJS calls Paycron API to initiate eCheck payment
    --> Customer verifies bank account (Plaid instant or manual entry)
    --> Customer accepts ACH debit mandate

9b. ACH payment enters processing
    --> T+0: Payment submitted to ACH network
    --> T+2 to T+4: Bank processes debit
    --> T+4 to T+6: Funds arrive in Mercury account

10b. Paycron sends webhook to MedusaJS
     --> Payment status updated: pending --> captured
     --> Order status transitions to confirmed

5.4 Order Confirmation and Fulfillment

11. Order confirmed
    --> MedusaJS creates order record in PostgreSQL
    --> Email notification sent via Zoho Mail (order confirmation)
    --> Customer sees order confirmation page

12. Fulfillment
    --> Admin reviews order in MedusaJS dashboard
    --> Items picked, packed (per fulfillment SOP)
    --> Shipping label generated (USPS/UPS/FedEx)
    --> Tracking number recorded in MedusaJS
    --> Customer receives shipping notification email

13. Delivery
    --> Signature required for orders >= $150
    --> Tracking status updated via carrier webhooks
    --> Customer receives delivery confirmation email

5.5 Accounting

14. Transaction recorded
    --> USD payments: transaction flows through Mercury, syncs to Zoho Books
    --> BTC payments: BTCPay records BTC amount, tx hash, FMV in USD
    --> BTC CSV export imported to Koinly monthly for tax tracking

15. Monthly reconciliation
    --> Match MedusaJS orders to payment records
    --> BTC: reconcile BTCPay invoices with Medusa order IDs
    --> ACH: reconcile Paycron settlements with Mercury deposits
    --> Zoho Books: P&L, balance sheet, tax summary
    --> Koinly: BTC income at FMV, capital gains tracking

6. Security Architecture

Network Security

  • Cloudflare WAF -- Web Application Firewall on all proxied domains, blocks common attack patterns
  • Cloudflare DDoS protection -- Automatic L3/L4/L7 DDoS mitigation
  • HTTPS everywhere -- All public endpoints use TLS (Cloudflare edge certs for proxied domains, Let's Encrypt for BTCPay)
  • BTCPay direct connection -- Not proxied through Cloudflare to preserve WebSocket and Lightning compatibility

Bitcoin Security

  • Self-hosted BTCPay Server -- No third-party custody of Bitcoin; keys never leave the server or hardware wallet
  • Hardware wallet for cold storage -- Coldcard or Trezor; seed phrase stamped on metal, stored physically
  • xpub-only on-chain receiving -- BTCPay generates receiving addresses from xpub; spending requires hardware wallet signature
  • Lightning hot wallet -- CLN manages channel keys on server; funded proportional to expected weekly volume (~500K sats)
  • Sweep policy -- On-chain balance swept to cold storage at 0.01 BTC threshold via PSBT signed on hardware wallet
  • Tor-enabled -- nix-bitcoin runs Bitcoin and Lightning P2P over Tor by default
  • Encrypted backups -- Daily automated backup of BTCPay PostgreSQL and CLN database, encrypted with GPG

Credential Security

  • 1Password -- All business credentials stored in 1Password vault (existing subscription)
  • TOTP 2FA -- 1Password serves as TOTP authenticator for all services that support it
  • Zoho 2FA -- MFA enabled on Zoho Workplace for email access
  • Mercury 2FA -- Personal carrier phone number used for bank 2FA (not VoIP, per bank requirements)
  • API keys -- BTCPay API key, webhook secrets, and payment provider credentials stored in server environment variables and 1Password

Privacy and Compliance

  • No unnecessary PII storage -- MedusaJS stores only data required for order fulfillment
  • CCPA compliance -- Privacy request handling via privacy@research-relay.com and web form
  • DNT signals honored -- Non-essential tracking disabled when Do Not Track is detected
  • Identity separation -- Business operations use business email/phone; personal details limited to bank KYC and state filings
  • Northwest RA address -- Used for all public-facing disclosures; home address only in bank KYC files

7. Environments

Development

  • Local machine using devenv/nix for reproducible environment
  • MedusaJS dev server with hot reload
  • Local PostgreSQL database
  • BTCPay Server on Bitcoin testnet/signet (or mock for unit tests)
  • See: dev/medusa-dev-setup.md

Staging

  • TBD -- Options under evaluation:
    • Railway preview environments (automatic per PR)
    • Separate VPS with staging database
    • Docker Compose on development machine
  • BTCPay on Bitcoin testnet for payment flow testing

Production

Service Host Notes
MedusaJS + PostgreSQL VPS (provider TBD) Estimated $20-40/mo
Next.js Storefront Cloudflare Pages (free tier) Static generation + edge functions
BTCPay + CLN + bitcoind shops-btc-01 (existing NixOS server) Already provisioned
MkDocs Cloudflare Pages (free tier) Deployed from this repo
DNS Cloudflare Domain registered at Cloudflare Registrar

8. Monthly Cost Summary

Estimated recurring infrastructure costs once all systems are operational:

Core Infrastructure

Service Provider Monthly Cost Notes
VPS (Medusa + PostgreSQL) TBD $20--40 4 CPU, 8 GB RAM, NVMe recommended
Cloudflare Pages Cloudflare $0 Free tier for storefront + docs
Domain Cloudflare Registrar ~$1 ~$12/year for .com
BTCPay Server Self-hosted (shops-btc-01) $0 Server already provisioned

SaaS Services

Service Provider Monthly Cost Notes
Business Email Zoho Workplace $3 Workplace Standard plan
Business Phone OpenPhone $15 Starter plan
Password Manager 1Password $0 Existing subscription
Accounting Zoho Books $0--20 Free plan initially, Standard at $15-20/mo
Crypto Accounting Koinly ~$4 $49/year
Sales Tax Avalara or TaxJar $50--300 Depends on transaction volume and states
Banking Mercury $0 Free business checking

Payment Processing (Per-Transaction)

Method Provider Fee Structure
BTC / Lightning BTCPay (self-hosted) ~$0 receiving; ~$4-12/mo liquidity management
ACH / eCheck Paycron Custom pricing (est. 1-3% per transaction)
Card (future) Easy Pay Direct / Durango Custom pricing (est. 4-8% + reserves)

Monthly Total Estimate

Category Low High
Infrastructure $21 $41
SaaS Services $73 $343
Total (excl. per-txn fees) $94 $384

The wide range for SaaS is driven primarily by sales tax service costs ($50-300/mo). All other services are relatively fixed. Payment processing fees are transaction-dependent and not included in the monthly total.


  1. BTCPay Server requires direct connections for WebSocket support and Lightning Network compatibility. Use Let's Encrypt via ACME on the server itself rather than Cloudflare proxy.