← Back to Exercise 2 of 3

Exercise 3 of 3 — The Big One: QBO Bill Import Middleware

This is the graduation exercise. You're going to build a middleware application that connects to QuickBooks Online, authenticates via OAuth, and imports vendor bills through the API. If you finish this, you can build anything. Estimated time: 1.5–2 hours.

0 / 0 steps
1
What Is Middleware & Why Build It?
Middleware is software that sits between two systems and makes them talk to each other. Your client has QuickBooks. They also have vendor invoices (PDFs, paper, emails). Right now, someone manually types those invoices into QBO. Your middleware automates that — it takes the invoice data and pushes it into QBO through the API.

What is an API?

An API (Application Programming Interface) is a set of rules for how software talks to other software. When you log into your bank's website, you're using a user interface (UI) — buttons, forms, visual stuff. An API is like a UI for software. Your code sends a structured request ("create a bill with this vendor for this amount") and QBO processes it, just as if someone had typed it in manually.

What is OAuth?

OAuth is how QBO knows your app is allowed to access the account. Think of it like a valet key — you give the valet a special key that starts the car but won't open the trunk. OAuth gives your app limited access to QBO without sharing the owner's password. The user clicks "Authorize," QBO confirms, and your app gets a token (a temporary pass) to make requests.

Sandbox vs. Production:

  • Sandbox — A fake QBO company with fake data. Free, safe, can't break anything. This is where you develop and test. You can create fake bills, fake vendors, fake everything.
  • Production — A real QBO company with real data. Requires Intuit to review and approve your app. This is where your middleware would actually run for a client.

You're starting with the sandbox. Same code works in both — the only difference is the URLs and credentials.

What a real build looks like:

We have built a full invoice processing middleware for a client. It ingests PDFs, parses line items, maps products to QBO inventory items, learns vendor patterns over time, validates everything, then pushes finished bills into QuickBooks. It handles BOLs, freight calculations, pricing lookups, and drift detection.

Yours does one thing: import a bill. That's the seed. Everything else grows from it.

2
Install Python

The middleware runs on Python using Flask (a lightweight web framework). The exercises so far were just HTML files — this one is a real application with a server.

Download Python
CRITICAL: On the very first screen of the installer, check the box that says "Add python.exe to PATH" at the bottom. This is the one checkbox you must not skip. If you miss it, nothing that follows will work.
Verify it worked — open a NEW Command Prompt (close any old ones first) and type:
python --version
If Python was already installed, skip this section. You just need version 3.11+.
3
Set Up Your Intuit Developer Account

To talk to QuickBooks through the API, you need a developer account with Intuit (the company that makes QBO). This is free and gives you a sandbox environment to play with.

Heads up on the portal layout: Intuit redesigns this developer site often, so the exact button names and menu positions below may not match what you see. The concepts don't change — you're creating an app, copying its Client ID and Client Secret, adding a redirect URI, and finding your sandbox company. Hunt for those ideas, and if a label looks different, tell Claude Code what's on your screen and it'll orient you.
Open Intuit Developer Portal

Create an app:

Get your credentials:

After creating the app, find the section called Keys & OAuth (sometimes labeled "Keys & credentials," or tucked under "Development Settings"). Look for those words rather than an exact button. You need three things from here:

Keep these credentials private. Your Client ID and Client Secret are like a username and password for your app. Don't share them, don't post them online, don't commit them to Git. Claude Code will store them in a config file that stays on your machine.

Set the redirect URI:

This tells Intuit where to send the user after they authorize your app. Since your app runs on your own computer:

http://localhost:5000/callback

Find your sandbox company:

Intuit automatically creates a sandbox QBO company for testing. It has fake vendors, fake invoices, fake everything.

You can click "Go to company" to open the sandbox QBO. Poke around — it looks just like real QBO but with fake data. After you import a bill through your middleware, you'll check for it here.
You now have everything you need from Intuit:
• Client ID
• Client Secret
• Redirect URI (http://localhost:5000/callback)
• Sandbox Company ID

Keep these in your text file. You'll paste them into Claude Code in a moment.
4
Set Up the Project
cd C:\dev\BillImporter
claude

First, have Claude set up the project structure. This prompt includes your Intuit credentials — replace the placeholders with your actual values:

Prompt: Set up the middleware project Set up this project. Create: 1. CLAUDE.md (at the project root) - I'm [your name], a [your role]. Learning to build middleware with Claude Code. Propose plans before building. Deliver complete files. Explain what you're doing. 2. context/PROJECT.md - We're building a simple QBO bill import middleware. Flask app on localhost:5000. Connects to QBO sandbox via OAuth. User can enter bill details (vendor, date, amount) and import them to QBO. 3. context/JOURNAL.md - Starting project. Setting up workspace. 4. A .env file with these values (DO NOT commit this to git): QBO_CLIENT_ID=YOUR_CLIENT_ID_HERE QBO_CLIENT_SECRET=YOUR_CLIENT_SECRET_HERE QBO_REDIRECT_URI=http://localhost:5000/callback QBO_ENVIRONMENT=sandbox QBO_COMPANY_ID=YOUR_COMPANY_ID_HERE 5. A .gitignore that excludes .env files Replace the placeholder values with my credentials, which I'll provide now: Client ID: [paste yours] Client Secret: [paste yours] Company ID: [paste yours]
Your .env file contains secrets. The .gitignore ensures it won't get uploaded if you ever use Git. But also: don't copy your .env file to other computers, don't email it, and don't paste its contents into any chat or forum.
5
Build the Middleware

Now for the big build. This prompt tells Claude to create the entire Flask application. It's longer than previous prompts because there's more to build, but the pattern is the same — describe what you want, Claude builds it.

Prompt: Build the bill importer Build a Flask application for importing bills into QuickBooks Online. Here's what I need: ARCHITECTURE: - app.py as the main Flask app (port 5000) - Load credentials from .env using python-dotenv - Use the intuit-oauth library (it imports as intuitlib) and python-quickbooks for QBO integration - Store OAuth tokens in a local JSON file (tokens.json) so I don't have to re-authorize every time PAGES: 1. Home page (/) - Dashboard showing: - Connection status (connected/disconnected to QBO) - "Connect to QuickBooks" button if not connected - Link to the bill import form if connected 2. Bill Import page (/import) - A form with: - Vendor name (dropdown that pulls vendors from QBO) - Invoice/Bill number (text field) - Bill date (date picker, defaults to today) - Due date (date picker) - Line items section: - Description (text) - Amount (number) - A button to add more line items - "Import to QuickBooks" submit button 3. Success page - Shows confirmation after a bill is imported, with the QBO bill ID OAUTH FLOW: - /connect route redirects to Intuit's OAuth page - /callback route handles the OAuth callback - Store access_token and refresh_token in tokens.json - Auto-refresh expired tokens REQUIREMENTS: - Install all Python packages needed (flask, python-dotenv, intuit-oauth, python-quickbooks) - Create a requirements.txt - Clean, professional UI (use Bootstrap 5 for styling) - Error handling with user-friendly messages - Show clear status messages throughout the process Keep it simple. No PDF upload for now, no parsing, no inventory tracking. Just: enter bill details, push to QBO. The simplest possible working middleware. After building, start the Flask server so I can test.
This build takes longer than the previous exercises. Claude is creating multiple files (app.py, templates, requirements.txt), installing Python packages, and possibly setting up the Flask server. Let it work. If it asks you to approve running commands (like pip install), say yes.
If Claude didn't start the server, ask it: "Start the Flask server for me." Or you can ask Claude to run python app.py. You should see something like * Running on http://127.0.0.1:5000 in the output.
6
Connect to QuickBooks

The server is running. Now let's connect it to your QBO sandbox.

You should see a dashboard page with a "Connect to QuickBooks" button (or something similar). The status should show "Not Connected."

This should redirect you to Intuit's authorization page. You'll log in with your Intuit developer account and authorize the app to access your sandbox company.

After authorizing, Intuit sends you back to your app (the redirect URI). Your app captures the authorization code, exchanges it for tokens, and saves them.

Your middleware is connected to QuickBooks Online. The OAuth dance is complete. Your app can now make API calls to QBO on behalf of your sandbox company. The tokens are saved locally, so you won't have to re-authorize every time you restart the server.
If the connection failed, go back to Claude Code and tell it what happened. Paste any error messages. Common issues:
• Redirect URI mismatch — make sure http://localhost:5000/callback is exactly what you entered in the Intuit portal
• Wrong Client ID or Secret — double-check the .env file
• Make sure you're using the sandbox credentials, not production
7
Import Your First Bill

The moment of truth. You're going to create a bill in QBO through your middleware.

Now verify it actually made it into QBO:

You just pushed data into QuickBooks Online through the API.

Think about what happened: you typed information into YOUR app, your app talked to QBO's servers through the API, and a bill appeared in QuickBooks. No manual data entry. No copy-pasting. Software talking to software.

This is what middleware does. This is the pattern for everything.
8
Sandbox vs. Production — What Changes?

You've been working in the sandbox. When you're ready to go to production (real QBO data for a real client), here's what changes:

  • App review: Intuit reviews your app before it can access real QBO companies. This takes a few days to a few weeks depending on complexity.
  • Credentials: You get a separate production Client ID and Client Secret. You update the .env file.
  • Environment flag: Change QBO_ENVIRONMENT=sandbox to QBO_ENVIRONMENT=production in your .env file.
  • Redirect URI: You add a production redirect URI in the Intuit portal (same URL if running locally, or your server's URL if hosting it).
  • The code itself: Doesn't change. Same Flask app, same API calls, same everything.
You don't need to go to production right now. The sandbox proves you can do it. When a client engagement requires it, you'll go through the app review process. For now, the sandbox is your playground.
9
Save Progress & Wrap Up

Update your memory log with everything you accomplished:

Update context/JOURNAL.md with everything we did. Include the QBO connection status, what the app looks like, what we tested, and ideas for next features.
To stop the Flask server: Go to the Command Prompt window where the server is running and press Ctrl+C. To start it again later, navigate to the folder and run python app.py.
10
Where to Go From Here

You've built three things of increasing complexity:

  • A standalone tool (Eisenhower Matrix) — HTML only, no backend
  • A connected form (Homework Email) — HTML + Google Apps Script backend
  • A real middleware (Bill Importer) — Python + Flask + OAuth + QBO API

The pattern is always the same:

  1. Create a project folder with CLAUDE.md and a context/ folder (PROJECT.md, JOURNAL.md)
  2. Describe what you want to Claude
  3. Review the plan, approve it, let Claude build it
  4. Test, customize, iterate
  5. Update context/JOURNAL.md before closing

Ideas for what to build next:

  • Add PDF upload to the bill importer — attach the vendor invoice to the QBO bill
  • Build a client reporting dashboard that pulls data from QBO and visualizes it
  • Create a scheduling tool for your consulting sessions
  • Build a client portal where your clients can see their own data
  • Connect to other APIs — Mailchimp, HubSpot, Stripe, whatever your clients use

Every one of these follows the same pattern you just learned. The only difference is which API you're talking to and what the UI looks like. Claude handles the technical details. You handle the vision.

You Made It.

Three exercises. Three levels of complexity. One more page — the habits and harness settings that separate fighting the tool from cooperating with it.

On to Harness & Memory →



Back to the beginning