Skip to content

Spring Boot demo app showcasing QuickBooks Custom Fields API with OAuth 2.0 authentication. Demonstrates hybrid integration using REST API for customers/invoices and GraphQL API for custom field management.

License

Notifications You must be signed in to change notification settings

IntuitDeveloper/SampleApp-CustomFields-Java

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

QuickBooks Custom Fields API (Java/Spring Boot)

This Spring Boot app authenticates with QuickBooks via OAuth 2.0 (Java SDK), fetches Customers/Items via the Accounting API, and manages Custom Fields using the QuickBooks GraphQL API.

Features

  • Custom Fields Operations (UI demo)
    • Create a custom field via GraphQL
    • List existing custom fields via GraphQL
    • Disable a custom field definition via GraphQL
    • Activate a custom field definition via GraphQL
    • Create invoice with a custom field value via REST
    • Deep link to view the created invoice in QBO
    • Create customer with a custom field value via REST
    • Deep link to view the created customer in QBO
    • Direct deep link to the Custom Fields settings page in QBO
  • Hybrid Integration
    • REST (Accounting API) for Customers, Items, and Invoices
    • GraphQL for Custom Fields
  • OAuth 2.0 (Java SDK)
    • Discovery-based environment handling (sandbox/production)
    • Secure redirect with configurable URI
  • Diagnostics
    • Configurable logging for REST and GraphQL requests
    • Inline duplicate-name handling for customer creation (scoped error under the form with input focus)

Availability: Custom Fields GraphQL APIs are currently available in production environments only.

Dependencies

  • Spring Boot Web and Thymeleaf
  • QuickBooks Java SDKs: ipp-v3-java-devkit, oauth2-platform-api, ipp-v3-java-data (6.7.0)
  • JAXB for Java 17 compatibility: javax.xml.bind:jaxb-api, org.glassfish.jaxb:jaxb-runtime
  • Jackson Databind
  • Spring Session Core
  • Spring Boot Starter Test (test scope)

Prerequisites

  • Java 17 or higher
  • Gradle 7.0 or higher
  • QuickBooks Developer account and a QuickBooks Online company
  • ngrok (for local development)

Required OAuth Scopes

  • Note: Custom Fields GraphQL APIs are currently available in PRODUCTION only (not supported in Sandbox).

  • Ensure you connect to a production company when testing these scopes.

  • com.intuit.quickbooks.accounting — access accounting data (customers, items, invoices)

  • app-foundations.custom-field-definitions — manage custom field definitions (GraphQL)

  • app-foundations.custom-field-definitions.read — read custom field definitions (GraphQL)

Setup

  1. Clone the repository
git clone <repository-url>
cd SampleApp-CustomFields-Java
  1. Start ngrok
ngrok http 8080
  1. Configure your QuickBooks app
  • Visit the Intuit Developer Portal (https://developer.intuit.com/app/developer/myapps)
  • Create an app (or use an existing one)
  • Enable the scopes above
  • Add your redirect URI (e.g., https://your-ngrok-url.ngrok-free.app/callback)
  1. Configure application settings

Option A: Use environment variables

export QB_CLIENT_ID=your_client_id
export QB_CLIENT_SECRET=your_client_secret
export QB_REDIRECT_URI=https://your-ngrok-url.ngrok-free.app/callback
export QB_ENVIRONMENT=production   # or sandbox
export QB_GRAPHQL_URL=https://qb.api.intuit.com/graphql
export QB_BASE_URL=https://quickbooks.api.intuit.com
export QB_MINOR_VERSION=75
export QB_SCOPES="com.intuit.quickbooks.accounting,indirect-tax.tax-calculation.quickbooks"

Option B: Use application.yml via the provided template Location: src/main/resources/application.yml.template (reference only)

Copy this template to src/main/resources/application.yml and then edit values:

server:
  port: 8080
  forward-headers-strategy: framework
  servlet:
    session:
      cookie:
        secure: true
        same-site: none

spring:
  application:
    name: quickbooks-sdk-demo
  thymeleaf:
    cache: false
    prefix: classpath:/templates/
    suffix: .html
    
quickbooks:
  # INSTRUCTIONS: Copy this block into application.yml and replace with your credentials
  client-id: ${QB_CLIENT_ID:your_quickbooks_client_id_here}
  client-secret: ${QB_CLIENT_SECRET:your_quickbooks_client_secret_here}
  environment: ${QB_ENVIRONMENT:production}  # Custom Fields GraphQL is production-only
  redirect-uri: ${QB_REDIRECT_URI:https://your-ngrok-url.ngrok-free.app/callback}
  base-url: ${QB_BASE_URL:https://quickbooks.api.intuit.com}
  graphql-url: ${QB_GRAPHQL_URL:https://qb.api.intuit.com/graphql}
  minor-version: ${QB_MINOR_VERSION:75}
  deep-link-template: ${QB_DEEP_LINK_TEMPLATE:https://app.qbo.intuit.com/app/invoice?txnId=%s&companyId=%s}
  customer-deep-link-template: ${QB_CUSTOMER_DEEP_LINK_TEMPLATE:https://app.qbo.intuit.com/app/customerdetail?nameId=%s&companyId=%s}
  custom-fields-deep-link-template: ${QB_CUSTOM_FIELDS_DEEP_LINK_TEMPLATE:https://app.qbo.intuit.com/app/customfields?companyId=%s}
  scopes:
    - com.intuit.quickbooks.accounting
    - app-foundations.custom-field-definitions
    - app-foundations.custom-field-definitions.read

logging:
  level:
    com.quickbooks.demo: DEBUG
    org.springframework.graphql: DEBUG
    org.springframework.web.client.RestTemplate: DEBUG

Notes:

  • The live application.yml is intentionally gitignored to protect secrets. Only the .template file is committed as a reference.
  • Do not edit the .template file for your environment; create/maintain your own application.yml locally.
  1. Run the application
./gradlew bootRun

Usage

  1. Visit http://localhost:8080
  2. Click "Connect to QuickBooks" to authenticate (/qbo-login)
  3. After auth, the home page loads Customers and Items from your QBO company
  4. Enter a custom field name and click "Create Custom Field" (GraphQL)
  5. (Optional) Use "Disable Custom Field" to deactivate an existing custom field definition
  6. (Optional) Use "Activate Custom Field" to reactivate a previously disabled custom field definition
  7. (Optional) Create a Customer with a custom field value (REST)
    • If a duplicate name is submitted, an inline error appears right under the form and the name field is focused for quick correction
    • Follow the deep links to view the customer or open the Custom Fields settings page directly
  8. Select a customer and item, optionally provide a custom field value, and click "Create Invoice" (REST)
  9. Follow the deep link to open the invoice in QBO

Screenshots

Step 1 — OAuth connect

Step 1 — OAuth

Step 2 — Create Custom Field

Step 2 — Create Custom Field

Step 3 — Disable Custom Field (optional)

Step 3 — Disable Custom Field

Step 4 — Create Invoice

Step 4 — Create Invoice

Step 5 — View Custom Fields in QBO

Step 5 — Custom Field in QBO

Step 6 — Customer Custom Field

Step 6 — Customer Custom Field

Endpoints

  • / — Home page
  • /qbo-login — Initiate OAuth flow
  • /callback — OAuth callback
  • /create_custom_field — Create a custom field (GraphQL)
  • /disable_custom_field — Disable a custom field definition (GraphQL)
  • /activate_custom_field — Activate a custom field definition (GraphQL)
  • /create_invoice — Create invoice with optional custom field (REST)
  • /create_customer — Create customer with optional custom field (REST)

API Reference: SDK ↔ API mapping

  • OAuth (SDK)

    • Build auth URL → SDK discovery (OpenID configuration) to determine endpoints
    • Exchange code → POST https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer
    • Refresh token → POST https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer
  • Accounting (REST)

    • Get Customers → POST {BASE}/v3/company/{realmId}/query?minorversion={mv} with body Select * from Customer ...
    • Get Items → POST {BASE}/v3/company/{realmId}/query?minorversion={mv} with body Select * from Item ...
    • Create Customer → POST {BASE}/v3/company/{realmId}/customer?minorversion={mv}
    • Create Invoice → POST {BASE}/v3/company/{realmId}/invoice?minorversion={mv}&include=enhancedAllCustomFields
      • Headers: Authorization: Bearer <token>, Content-Type: application/json, Accept: application/json
  • Custom Fields (GraphQL)

    • Create Custom Field → POST https://qb.api.intuit.com/graphql (mutation in static/graphql/custom_fields.graphql)
    • List Custom Fields → POST https://qb.api.intuit.com/graphql (query in static/graphql/custom_fields.graphql)

Notes:

  • {BASE} is typically https://quickbooks.api.intuit.com (prod) or sandbox host if configured.
  • minorversion is configurable in application.yml.

Project Structure

SampleApp-CustomFields-Java/
├── src/main/java/com/quickbooks/demo/
│   ├── Application.java
│   ├── config/
│   │   └── QuickBooksConfig.java
│   ├── controller/
│   │   └── QuickBooksController.java
│   └── service/
│       ├── CustomFieldsService.java
│       ├── QuickBooksApiService.java
│       └── QuickBooksOAuthService.java
├── src/main/resources/
│   ├── application.yml
│   ├── static/graphql/
│   │   ├── custom_fields.graphql
│   │   └── custom_field_variables.json
│   ├── static/css/
│   └── templates/
└── README.md

Common Issues

  1. Insufficient scope (GraphQL error: access denied / AUTHORIZATION_DENIED)
  • Ensure GraphQL scopes are configured and granted during auth
  • If you change scopes, re-authenticate to obtain a new token
  1. Invalid client or redirect URI
  • Verify Client ID/Secret
  • Ensure redirect-uri exactly matches the Developer Portal configuration
  1. Environment mismatch
  • Ensure environment matches the company you connect to (sandbox vs production)
  1. Custom Field Limits
  • You may reach business limits for the number of custom fields; use an existing field or contact your admin

License

This project is licensed under the Apache License 2.0 — see LICENSE.

Support

For support, visit the Intuit Developer Community (https://help.developer.intuit.com/s/) or open an issue in this repository.

About

Spring Boot demo app showcasing QuickBooks Custom Fields API with OAuth 2.0 authentication. Demonstrates hybrid integration using REST API for customers/invoices and GraphQL API for custom field management.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published