The Challenge
Sales closes a deal in HubSpot. Now someone has to open Rev.io, find the customer account, create the billing services, copy over every line item, match the pricing exactly, and make sure nothing gets duplicated. That handoff is where things break.
Services get missed. Someone forgets to add the SIP trunking fee. Pricing gets copied wrong because the HubSpot SKU doesn't match the Rev.io product name. A service gets created when the customer already has it billed, which doesn't increase the quantity on the existing line — it creates a whole new line item. Now you've got two charges for the same thing. Every mistake compounds: missed revenue, billing disputes, support tickets, corrections that take hours.
The team wanted automation but couldn't risk blind synchronization. Billing is the source of truth. If the system creates duplicate services or bills the wrong amount, that's worse than manual entry. We needed middleware that could move fast but pause for human judgment where it matters.
The Approach
The solution is a state machine workflow that treats every deal as a multi-step process with approval gates. Zapier triggers when a HubSpot deal hits a specific stage. The middleware ingests the deal data, fetches all line items and company details, then stops at the first gate: human provisioning review.
A provisioning engineer sees every deal in a queue. For each line item, they assign it to a customer account (parent or child), and the system checks Rev.io to see if that service already exists. If the service is already provisioned and billed, the system flags it — because creating it again wouldn't increase the quantity on the existing line, it would add an entirely new line item. The engineer reviews the flags, adjusts assignments if needed, and approves.
Once approved, the system submits a billing request to Rev.io. The revenue ops team reviews and approves the request through Rev.io's standard workflow. The middleware listens for the webhook confirmation, then creates the services. Every state transition writes an audit event. Every price comes directly from HubSpot line items — no rounding, no guessing, no manual re-entry.
State Machine Flow
Technical Stack
- Backend: Node.js 24 with Express, Zod validation for all API inputs
- Frontend: React 18 with Vite, Tailwind CSS, shadcn/ui components
- Database: PostgreSQL 16 for state tracking, audit events, SKU mappings
- Queue: Redis 7 + BullMQ for async job processing
- Auth: Azure AD SAML with role-based access control
- Proxy: Caddy 2 for automatic HTTPS and reverse proxy
Validation Rules
Before a provisioning engineer can approve a deal, the system enforces blocking validation:
- Every line item must have a child account assigned
- Every HubSpot SKU must map to a known Rev.io product ID
- For quantity increments, an existing service ID must be selected
- HubSpot pricing must be present and numeric
If any rule fails, the approve button stays disabled and the UI highlights what's missing. No guessing, no skipping steps.
Architecture Diagram
The Outcome
Accidental line items stopped appearing. The system checks Rev.io before creating anything new — if a customer already has a service provisioned and billed, the middleware flags it instead of blindly creating another line item. Without that check, Rev.io would add a new charge rather than increasing the quantity on the existing one. Pricing enforcement became exact: HubSpot line-item prices copy directly into Rev.io with no rounding or manual transcription errors.
The audit trail captures everything. State transitions, approvals, and Rev.io submissions all get logged with timestamps and user IDs. When billing disputes happen, the team pulls the deal's event log and sees exactly what was approved, when, and by whom.
Human oversight stayed where it matters. Provisioning engineers still review every deal and make account assignment decisions. The system doesn't guess which child account to bill or whether to create a new service versus incrementing an existing one. It presents the data, enforces the rules, and waits for approval. Automation handles the repetitive API calls and data synchronization. Humans handle the judgment calls.
Rev.io remains the source of truth. The middleware never bypasses Rev.io's approval workflow. It creates requests, waits for webhooks, and only finalizes services after the revenue ops team approves through Rev.io's standard process. That preserves the existing approval workflow while eliminating the manual copy-paste work that used to take hours per deal.