DealFlow is an open-source Discord commerce operating system built entirely with JavaScript, Node.js, discord.js, and MongoDB. It helps Discord-based shops manage products, quotes, coupons, currencies, structured orders, staff, payments, milestones, encrypted digital inventory, subscriptions, customer relationships, loyalty, marketing attribution, deliveries, verified reviews, disputes, audit logs, and business statistics without requiring an external website.
Discord is the complete product interface. Customers and staff use slash commands, buttons, select menus, modern labelled modals, Components V2 containers, private channels, private threads, direct messages, and scheduled notifications.
- Discord-native product catalog and public order panel
- Components V2 interface with containers, text displays, separators, media galleries, and native action rows
- Configurable order request modal
- Private order channel with history, delivery, and staff-note threads
- Structured order status, price, deadline, progress, payment, and assignment tracking
- Automatic read-only EVM wallet tracking for native assets and ERC-20 tokens
- Unique payment fingerprints, block-confirmation tracking, duplicate protection, and a Discord wallet ledger
- Payment Reconciliation Center and post-confirmation reorganization monitoring
- Versioned quotes with coupons, tax, validity, revision limits, and customer acceptance buttons
- Manual currency rates, conversion fees, reverse conversion, and locked order totals
- Deposit and milestone payment workflows
- CRM profiles with private notes, tags, blocking controls, and explainable TrustGraph scores
- Loyalty points and configurable customer tiers
- Counted stock and AES-256-GCM encrypted license-key inventory
- Recurring subscription records with due and past-due reminders
- Marketing campaigns, affiliate attribution, and commission tracking
- Invoices, structured revisions, refund records, and inventory release on cancellation
- Discord conversion funnel from product selection through verified review
- Searchable Discord knowledge base and private support tickets with priority-based SLA alerts
- Discord attachment, link, code, and text delivery support
- Customer delivery confirmation
- Deal Passport generated only after a real completed order
- Verified reviews that staff cannot create manually
- Private dispute channels with evidence and moderator controls
- Full audit log for sensitive actions
- Deadline reminders and overdue alerts with
node-cron - Daily and weekly reports posted in a private management channel
- Role-based permission checks repeated for every interaction
- Automatic staff assignment based on specialty, capacity, workload, rating, and manual priority
- Live order health indicator for missing assignments, approaching deadlines, overdue work, and disputes
- Explainable FlowPulse risk algorithm with confidence, trend, factor breakdown, and recommended actions
- Data isolation by Discord guild
- JavaScript only — no TypeScript
- Node.js 20+
- discord.js 14
- MongoDB and Mongoose
- ethers v6 for read-only EVM JSON-RPC access
- Joi validation
- node-cron scheduled tasks
- Pino structured logging
- Vitest and ESLint
- Optional Docker deployment
Discord interaction
-> interaction router
-> runtime permission check
-> Joi input validation
-> service layer
-> Mongoose model operation
-> audit log
-> Discord response
-> scheduled notification when required
Buttons, select menus, modals, and slash commands reuse the same services. No HTTP server or separate frontend is included.
src/
commands/ Slash-command definitions
config/ Environment, constants, and logging
database/ MongoDB connection
events/ Discord event handlers
interactions/ Commands, buttons, select menus, and modals
jobs/ Deadline and report schedules
models/ Orders, payment intents, wallet ledger, and other Mongoose models
permissions/ Role and order access checks
services/ Business logic
utils/ Discord UI and formatting helpers
validators/ Joi schemas
scripts/ Slash-command deployment
tests/ Automated tests
docs/ Architecture documentation
git clone https://github.com/PingusWasHere/DealFlow.git
cd dealflow
npm install
cp .env.example .envConfigure .env:
DISCORD_TOKEN=
CLIENT_ID=
MONGODB_URI=mongodb://localhost:27017/dealflow
GUILD_ID=
LOG_LEVEL=info
NODE_ENV=development
TIMEZONE=Europe/Paris
EVM_RPC_URL=
PAYMENT_SCAN_CRON=*/1 * * * *
DATA_ENCRYPTION_KEY=
PASSPORT_SIGNING_KEY=DATA_ENCRYPTION_KEY and PASSPORT_SIGNING_KEY should be independent random secrets containing at least 32 characters. The first encrypts digital inventory. The second authenticates newly generated Deal Passports.
GUILD_ID is recommended during development because guild commands update immediately. Remove it before deploying global commands.
- Create an application in the Discord Developer Portal.
- Add a bot and copy its token into
DISCORD_TOKEN. - Enable the bot installation scope and the
applications.commandsscope. - Invite the bot with the permissions below.
- Register slash commands.
npm run deploy-commands- View Channels
- Send Messages
- Embed Links
- Attach Files
- Read Message History
- Use Application Commands
- Manage Channels
- Manage Threads
- Manage Messages
The bot needs Manage Channels and Manage Threads to create private order spaces and their associated threads.
Use a local MongoDB instance, MongoDB Atlas, or Docker Compose.
docker compose up -d mongodbEach stored document includes a guildId. Queries always include the current guild to prevent data leakage between Discord servers.
npm run dev
npm run lint
npm test
npm run deploy-commandsStart production mode:
npm startdocker compose up -d --build
docker compose logs -f botSecrets must stay outside source control. Never commit .env.
/shop setup/panel publish
/product create/product list/product edit/staff add/staff availability/staff profile
/order view/order assign/order autoassign/order pulse/order status/order progress/order deadline/order complete/order cancel/revision request/revision list/revision status/workflow add/workflow list/workflow apply/workflow remove
/commerce setup/currency set/currency convert/currency lock/currency list/coupon create/coupon list/quote create/quote view/milestone add/milestone list/milestone request/milestone approve/invoice create/invoice view
/payment setup/payment request/payment status/payment verify/payment wallet/payment unmatched/payment reconcile/payment confirm/payment refund/delivery send
/customer profile/customer update/customer block/customer note/loyalty adjust/inventory setup/inventory add-key/inventory status/inventory deliver/subscription create/subscription list/subscription status/subscription renew/campaign create/campaign apply/campaign list/campaign stats/campaign attribute/affiliate register/affiliate stats
/passport verify/stats overview/stats products/stats staff/stats monthly/stats export/conversion overview
/support article-add/support search/support open/support list/support respond/support close/dispute view/dispute summary
Additional actions are exposed contextually through buttons, select menus, and modals inside each private order channel.
FlowPulse calculates an explainable 0–100 operational risk score for every active order. It combines deadline trajectory, progress gap, inactivity, staff capacity, payment state, repeated revisions, deadline extensions, missing deliveries, and disputes.
The result includes:
- A risk level: Stable, Watch, At Risk, or Critical
- A confidence score based on available data
- A rising, stable, or falling trend
- Exact point contributions for every factor
- Prioritized corrective actions
- Private alerts when a score crosses 70 or rises sharply
- A six-hour anti-spam window for repeated alerts
The engine is deterministic and auditable. It does not make hidden AI decisions.
DealFlow calculates quote totals in a strict order: subtotal, coupon discount, taxable amount, tax, and final total. Percentage coupons cannot exceed 100%, fixed discounts cannot create a negative total, usage periods and customer limits are checked, and accepted quote values are copied into the order as a commercial snapshot.
Currency rates are controlled by shop managers. A rate can include a conversion fee and expiration. /currency lock stores the source currency, target currency, effective rate, fee, and lock time directly in the order before replacing its displayed total. DealFlow does not claim that a manually entered rate is a live market rate.
The bot records operational commerce events generated by real Discord actions:
PANEL_VIEWED
-> PRODUCT_SELECTED
-> MODAL_OPENED
-> MODAL_SUBMITTED
-> ORDER_CREATED
-> QUOTE_ACCEPTED
-> PAYMENT_CONFIRMED
-> DELIVERY_ACCEPTED
-> ORDER_COMPLETED
-> REVIEW_SUBMITTED
/conversion overview calculates stage counts, stage-to-stage conversion, order-to-payment conversion, and confirmed funnel value. Campaign and affiliate codes are stored on the order and copied into payment conversion events.
Customer profiles are scoped to one Discord server. They store preferences, internal tags and notes, loyalty balances, shop-level blocking state, order statistics, and a TrustGraph snapshot. TrustGraph is deterministic and explainable: completed orders and confirmed history add confidence, while cancellations and disputes reduce the score. It is advisory and never automatically bans, sanctions, or refuses a customer.
Confirmed payments award loyalty points once. Cumulative refund increases remove the corresponding points. Tiers are selected from the shop commerce settings.
Counted inventory is decremented atomically when an order is created and restored when an eligible order is cancelled. License-key inventory reserves one available encrypted secret for the new order. Keys use AES-256-GCM with DATA_ENCRYPTION_KEY, are never displayed in inventory reports, and are decrypted only immediately before a private Discord delivery. Failed delivery attempts restore the prior reservation state.
Subscriptions are tracking records rather than automatic charges. They contain a customer, recurring amount, interval, next billing date, grace period, and explicit status. An hourly job reports upcoming renewals and past-due records in the private management channel. Managers advance a successful cycle with /subscription renew.
Managers maintain searchable support articles while customers use /support search without leaving Discord. A customer can escalate to a private ticket with a priority-based first-response target. Managers record the first response explicitly, resolve the ticket with a written outcome, and receive private SLA alerts when the response target is missed. One customer can have at most three active tickets.
Every newly generated Deal Passport receives a canonical SHA-256 integrity hash. When PASSPORT_SIGNING_KEY is configured, it also receives an HMAC-SHA-256 signature. /passport verify recomputes the proof with constant-time signature comparison and rejects modified records.
DealFlow includes an EVM payment tracker for native currencies such as ETH and ERC-20 tokens such as USDC. It is a read-only verification system: the bot receives no seed phrase, never signs a transaction, cannot move funds, and does not perform refunds. One RPC endpoint is supplied through EVM_RPC_URL; the configured chain ID is checked against that endpoint before settings are saved.
An administrator runs /payment setup and defines:
- Network name and EVM chain ID
- Receiving wallet address
- Native asset or ERC-20 token mode
- Asset symbol and decimals
- ERC-20 contract address when applicable
- Number of required block confirmations
- Payment-fingerprint size
- Underpayment tolerance in basis points
- Number of blocks processed per scan
- Optional block-explorer transaction URL
The bot immediately verifies the RPC network, stores guild-isolated settings, records an audit event, and captures the first wallet snapshot.
When a manager runs /payment request, DealFlow converts the requested decimal amount into atomic units with ethers.parseUnits. It then adds a small deterministic suffix generated from an atomic per-server sequence. For example, a base request can become a slightly more precise exact amount. That exact amount acts as a payment fingerprint, allowing a transfer to be linked to one active order even when every order uses the same receiving wallet.
The generated atomic amount is checked against all active intents. A collision causes another sequence value to be tried. Automatic matching requires one and only one eligible intent. Ambiguous, underpaid, or overpaid transfers are recorded in the wallet ledger but are not silently assigned to an order.
The PAYMENT_SCAN_CRON job scans forward from the last successfully processed block. Reconfiguring a guild cancels its old active intents so requests from two networks cannot overlap:
- Native mode reads successful transactions sent directly to the configured wallet.
- ERC-20 mode reads successful standard
Transferevents emitted by the configured token contract and addressed to the wallet. - Every incoming transfer is upserted into
WalletTransactionusing the guild, chain ID, transaction hash, and log index as a unique identity. - The scan checkpoint advances only after the processed block range completes.
The scanner never searches outgoing transfers and never needs a private key.
Before a payment is confirmed, DealFlow verifies all of the following:
- The transaction exists and its receipt succeeded.
- The RPC chain matches the configured chain ID.
- The recipient is the configured wallet.
- The asset type and, for ERC-20, token contract match.
- The sender matches when an expected payer wallet was supplied.
- The atomic amount matches exactly or falls inside the explicitly configured tolerance.
- The transaction is not already linked to another payment intent.
- The receipt has reached the configured confirmation count.
Only then does the intent become CONFIRMED, the order payment become PAYMENT_CONFIRMED, the order card refresh, a confirmation appear in Discord, and an immutable audit entry get written.
Payment intents use explicit states:
PENDING: waiting for a transferDETECTED: a hash exists but has not produced a final receiptCONFIRMING: the transfer is valid but needs more blocksCONFIRMED: all checks passedUNDERPAID: the amount is below the accepted thresholdREVIEW_REQUIRED: an overpayment was detected and requires a manager decisionEXPIRED: no valid payment arrived in timeFAILED: the transaction revertedCANCELLED: a newer request replaced the intent
The scheduled job rechecks detected and confirming transactions, expires stale requests, and prevents overlapping scan runs.
Managers use /payment wallet to see a Components V2 tracker containing the configured network, read-only wallet, tracked asset balance, native gas balance, latest scanned block, pending intents, confirmation policy, and recent incoming transfers. Wallet balance snapshots are cached for 15 minutes and automatically deleted after 90 days. The transaction ledger remains available for audit and duplicate detection.
Customers can use the payment card buttons or /payment verify to submit a transaction hash. They never enter payment credentials in Discord.
- The current implementation supports EVM-compatible networks only.
- A single running bot instance uses one
EVM_RPC_URL; that endpoint must serve the chain configured by a guild. - RPC availability and provider block-range limits affect detection latency.
- Required confirmations reduce reorganization risk but cannot make a blockchain mathematically final on every network.
- Token decimals, contract address, wallet address, and chain ID must be verified by the shop owner.
- DealFlow tracks declared on-chain payments; it is not a bank, custodian, exchange, accounting system, or legal dispute arbiter.
Implementation references: Ethereum JSON-RPC, ERC-20, and ethers v6.
All bot-authored interface messages use Discord Components V2 with MessageFlags.IsComponentsV2. Traditional message content and embeds are not mixed with V2 messages. Deferred interaction responses are converted to V2 through the original-response edit endpoint, as required by Discord.
Order panels are built from reusable containers, text displays, separators, media galleries, and action rows. Modals use the modern Label component instead of the deprecated Action Row plus Text Input layout.
- Run
/shop setupand select the staff, manager, and moderator roles. - Create products with
/product create. - Publish the customer panel with
/panel publish. - Add staff profiles with
/staff add. - Use the private management channel for scheduled reports.
- Set
EVM_RPC_URL, run/payment setup, and create order-specific requests with/payment requestif automatic wallet tracking is required. - Run
/commerce setupto configure base currency, tax, and loyalty rules. - Set independent
DATA_ENCRYPTION_KEYandPASSPORT_SIGNING_KEYsecrets before enabling encrypted inventory and signed passports.
- Runtime role checks for every sensitive command and component
- Guild-level data isolation
- Joi input validation
- Per-user interaction rate limiting
- Duplicate interaction protection
- Audit records for sensitive actions
- Attachment extension and size validation
- No bank card storage
- Read-only RPC access with no private keys, signing, withdrawals, or automatic refunds
- Chain, recipient, token, amount, receipt, confirmation, and duplicate-transaction checks
- Atomic stock reservation and rollback
- AES-256-GCM encryption for license keys
- Signed Deal Passport integrity proofs
- Two-strike post-confirmation transaction integrity monitoring
- Payment tracking only; DealFlow is not a payment processor or custodian
- Deal Passports and verified reviews require a completed database order
- Environment variables and Docker secrets remain outside source control
See SECURITY.md for responsible disclosure.
- Product administration
- Customer order panel and modal
- Private order channels and threads
- Staff assignment, deadlines, payments, deliveries, and history
- Deal Passports and verified reviews
- Disputes, statistics, and scheduled reports
- Quotes, coupons, tax, currency locking, and milestone payments
- CRM, loyalty, TrustGraph, campaigns, and affiliates
- Counted stock, encrypted license keys, subscriptions, invoices, and revisions
- Private CSV exports for orders, customers, and invoices
- Searchable support articles, private tickets, priorities, and SLA monitoring
- Automatic staff assignment by specialty and workload
- Quote line-item editor and product variant editor
- Multi-language configuration
- Signed payment-provider webhooks
- Neutral automated dispute summaries
- Discord-native FAQ assistant
- Optional live exchange-rate provider adapters
- Multi-RPC and non-EVM payment-provider adapters
Read CONTRIBUTING.md, open an issue, and submit a focused pull request with tests.
MIT — see LICENSE.
Use the repository issue tracker for bug reports, feature proposals, and security-neutral questions.