You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Laravel中集成QuickBooks PHP SDK并对接QuickBooks Online?

Hey there! Let's walk through integrating that Intuit OAuth2 PHP SDK into your Laravel project step by step— I’ll keep things clear and tailored to Laravel’s best practices since you mentioned you’re not super familiar with it yet.

Step 1: Install the SDK Properly (No Manual File Includes!)

Never manually include PHP files in Laravel— use Composer for package management instead, it’s the standard way and handles autoloading automatically. Run this command in your project root:

composer require intuit/oauth2-php

This will pull in the SDK and make all its classes available across your Laravel app without needing include or require statements.

Step 2: Migrate Your Configuration to Laravel’s System

Instead of using a standalone quickbooksconfig.php file, move your config to Laravel’s built-in config system for better security and maintainability:

  1. Create a new file config/quickbooks.php with your SDK settings:
    return [
        'client_id' => env('QUICKBOOKS_CLIENT_ID'),
        'client_secret' => env('QUICKBOOKS_CLIENT_SECRET'),
        'redirect_uri' => env('QUICKBOOKS_REDIRECT_URI'),
        'environment' => env('QUICKBOOKS_ENVIRONMENT', 'sandbox'), // Default to sandbox
    ];
    
  2. Add your sensitive credentials to your .env file (never commit this file to version control!):
    QUICKBOOKS_CLIENT_ID=your_intuit_client_id
    QUICKBOOKS_CLIENT_SECRET=your_intuit_client_secret
    QUICKBOOKS_REDIRECT_URI=https://your-app-url.com/quickbooks/callback
    QUICKBOOKS_ENVIRONMENT=sandbox
    
Step 3: Convert Existing Code to a Laravel Controller

Let’s create a dedicated controller to handle QuickBooks OAuth flows. Run this Artisan command first:

php artisan make:controller QuickbooksController

Then replace the controller content with this Laravel-friendly version of the SDK logic:

<?php

namespace App\Http\Controllers;

use Intuit\OAuth2\Client\Provider\IntuitProvider;
use Illuminate\Http\Request;

class QuickbooksController extends Controller
{
    // Redirect user to Intuit's authorization page
    public function redirectToAuth()
    {
        $provider = new IntuitProvider([
            'clientId' => config('quickbooks.client_id'),
            'clientSecret' => config('quickbooks.client_secret'),
            'redirectUri' => config('quickbooks.redirect_uri'),
            'environment' => config('quickbooks.environment'),
        ]);

        // Generate authorization URL with required scopes
        $authUrl = $provider->getAuthorizationUrl([
            'scope' => ['com.intuit.quickbooks.accounting'], // Adjust scopes as needed
        ]);

        // Store state in session to prevent CSRF attacks
        session(['oauth2state' => $provider->getState()]);

        return redirect()->away($authUrl);
    }

    // Handle Intuit's callback after authorization
    public function handleCallback(Request $request)
    {
        // Validate state to prevent CSRF
        if (empty($request->state) || $request->state !== session('oauth2state')) {
            session()->forget('oauth2state');
            return redirect()->route('home')->with('error', 'Invalid authentication state');
        }

        $provider = new IntuitProvider([
            'clientId' => config('quickbooks.client_id'),
            'clientSecret' => config('quickbooks.client_secret'),
            'redirectUri' => config('quickbooks.redirect_uri'),
            'environment' => config('quickbooks.environment'),
        ]);

        try {
            // Fetch access token using the authorization code
            $token = $provider->getAccessToken('authorization_code', [
                'code' => $request->code
            ]);

            // Store the token (save to database/session for future use)
            session(['quickbooks_token' => $token]);

            // Optional: Fetch user/company details from Intuit
            $resourceOwner = $provider->getResourceOwner($token);
            // dd($resourceOwner->toArray()); // Uncomment to test

            return redirect()->route('employees.directory')->with('success', 'Connected to QuickBooks successfully!');
        } catch (\Exception $e) {
            return redirect()->route('home')->with('error', "QuickBooks auth failed: {$e->getMessage()}");
        }
    }
}

Add these routes to routes/web.php to map the controller methods:

Route::get('/quickbooks/auth', [QuickbooksController::class, 'redirectToAuth'])->name('quickbooks.auth');
Route::get('/quickbooks/callback', [QuickbooksController::class, 'handleCallback'])->name('quickbooks.callback');
Step 4: Fix the Blade Template Issue

Your original Blade code had path problems and didn’t follow Laravel’s conventions. Update it to this:

<script type="text/javascript" src="https://appcenter.intuit.com/Content/IA/intuit.ipp.anywhere-1.3.3.js"></script>
<script>
    // Use Laravel's route helper to generate a reliable auth URL
    var redirectUrl = "{{ route('quickbooks.auth') }}";
    
    intuit.ipp.anywhere.setup({
        grantUrl: redirectUrl,
        datasources: {
            quickbooks : true,
            payments : true
        },
        paymentOptions:{
            intuitReferred : true
        }
    });
</script>

The key fixes here:

  • We use route('quickbooks.auth') instead of hardcoding the URL, which works across all environments.
  • We removed the manual include since we’re now using Laravel’s config system for SDK settings.
Bonus: Pro Tip for Cleaner Code

To avoid repeating the IntuitProvider initialization in every controller, bind it to Laravel’s service container. Add this to the register() method in App\Providers\AppServiceProvider.php:

use Intuit\OAuth2\Client\Provider\IntuitProvider;

public function register()
{
    $this->app->bind(IntuitProvider::class, function ($app) {
        return new IntuitProvider([
            'clientId' => config('quickbooks.client_id'),
            'clientSecret' => config('quickbooks.client_secret'),
            'redirectUri' => config('quickbooks.redirect_uri'),
            'environment' => config('quickbooks.environment'),
        ]);
    });
}

Now you can inject the provider directly into your controller methods without manually initializing it!

内容的提问来源于stack exchange,提问作者Sourav

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:07:59