ynab-sdk-laravel / ynab-sdk-laravel
An SDK for working with YNAB's API in Laravel.
Requires
- php: ^8.2
- guzzlehttp/guzzle: ^7.9.2
- guzzlehttp/promises: ^2.0.4
- illuminate/contracts: ^10.0||^11.0||^12.0
- spatie/laravel-package-tools: ^1.16
Requires (Dev)
- larastan/larastan: ^2.9||^3.0
- laravel/pint: ^1.14
- nunomaduro/collision: ^8.1.1||^7.10.0
- orchestra/testbench: ^10.0.0||^9.0.0||^8.22.0
- pestphp/pest: ^v3.7.4||^v2.36.0
- pestphp/pest-plugin-arch: ^v3.0||^v2.7.0
- pestphp/pest-plugin-laravel: ^v3.1.0||^v2.4.0
- phpstan/extension-installer: ^1.3||^2.0
- phpstan/phpstan-deprecation-rules: ^1.1||^2.0
- phpstan/phpstan-phpunit: ^1.3||^2.0
- projektgopher/whisky: ^0.7.1
- spatie/laravel-ray: ^1.40.0
This package is auto-updated.
Last update: 2025-06-16 01:58:17 UTC
README
Introduction
The YNAB SDK for Laravel provides an expressive interface for interacting with YNAB's API within a Laravel application.
Installation
You can install the package via composer:
composer require ynab-sdk-laravel/ynab-sdk-laravel
You can publish the config file with:
php artisan vendor:publish --tag="ynab-sdk-laravel-config"
This is the contents of the published config file:
return [ 'base_url' => 'https://api.ynab.com/v1', 'client' => [ 'id' => env('YNAB_SDK_LARAVEL_CLIENT_ID'), 'secret' => env('YNAB_SDK_LARAVEL_CLIENT_SECRET'), ], 'oauth' => [ 'base_url' => env('YNAB_SDK_LARAVEL_OAUTH_BASE_URL', 'ynab-oauth'), 'base_name' => env('YNAB_SDK_LARAVEL_OAUTH_BASE_NAME', 'ynab-oauth'), ], 'response_type' => env('YNAB_SDK_LARAVEL_RESPONSE_TYPE', 'code'), 'redirect_to' => [ 'use_route_names' => env('YNAB_SDK_LARAVEL_REDIRECT_TO_USE_ROUTE_NAMES', true), 'after_callback' => env('YNAB_SDK_LARAVEL_REDIRECT_TO_AFTER_CALLBACK', 'home'), 'after_refresh' => env('YNAB_SDK_LARAVEL_REDIRECT_TO_AFTER_REFRESH', 'home'), ] ];
Usage
Personal Access Tokens
You can enter a personal access token directly (see: https://api.ynab.com/#personal-access-tokens).
use YnabSdkLaravel\YnabSdkLaravel\Ynab; $ynab = new Ynab('insert-access-token-here');
This class exposes 9 resource methods for accessing YNAB's API (see: https://api.ynab.com/v1).
$ynab->user()
$ynab->budgets()
$ynab->accounts()
$ynab->categories()
$ynab->payees()
$ynab->payeeLocations()
$ynab->months()
$ynab->transactions()
$ynab->scheduledTransactions()
Each method within its resource aligns with an endpoint:
<?php declare(strict_types=1); namespace YnabSdkLaravel\YnabSdkLaravel\Resources; final class User extends Resource { /** * @link https://api.ynab.com/v1#/User/getUser */ public function get() { return $this->client->get('/user'); } }
Oauth
Oauth authentication must be used for applications that accept access tokens from other users (see: https://api.ynab.com/#oauth-applications).
Auth Url
The Auth Url can be retrieved with the OauthHelper
class.
use YnabSdkLaravel\YnabSdkLaravel\OauthHelper; OauthHelper::getAuthUrl();
The auth url uses the following configuration parameters:
[ 'client_id' => config('ynab-sdk-laravel.client.id'), 'redirect_uri' => route(config('ynab-sdk-laravel.oauth.base_name').'.callback'), 'response_type' => config('ynab-sdk-laravel.response_type'), ]
With the following parameters:
client_id=123
redirect_uri=https://my-app.com/ynab-oauth/callback
response_type=code
The auth url should be the following: https://app.ynab.com/oauth/authorize?client_id=123&redirect_uri=https%3A%2F%2Fmy-app.com%2Fynab-oauth%2Fcallback&response_type=code
When you click on the link, you should be sent to a YNAB page asking you to authorize.
The route used in the redirect_uri
should be equal to the Callback Route you register via the package.
Callback Route
Registring the Route
A configurable route macro is registered by the package.
Place Route::ynabSdkLaravelOauth();
in your routes file to instantiate it. By default, the url should look like this: https://your-site.com/ynab-oauth/callback
.
You can configure the $baseUrl
and $baseName
in the .env
like so:
YNAB_SDK_LARAVEL_OAUTH_BASE_URL='my-ynab-oauth'
YNAB_SDK_LARAVEL_OAUTH_BASE_NAME='my-ynab-oauth'
The route should then look like this: https://your-site.com/my-ynab-oauth/callback
.
The second variable is for the name, such that you can access the route using something like redirect()->route(config('ynab-sdk-laravel.oauth.base_name') . '.callback')
.
Accessing the Controller
The controller builds the route that is used to authenticate with YNAB. Here are the components:
$query = [ 'client_id' => config('ynab-sdk-laravel.client.id'), 'client_secret' => config('ynab-sdk-laravel.client.secret'), 'redirect_uri' => route(config('ynab-sdk-laravel.oauth.base_name').'.callback'), 'grant_type' => $request->query('grant_type', 'authorization_code'), 'code' => $request->query('code'), ]; $query = http_build_query($query); $ynabRequest = Http::post("https://app.ynab.com/oauth/token?$query")->throw(); $afterCallback = config('ynab-sdk-laravel.redirect_to.after_callback'); $redirectTo = config('ynab-sdk-laravel.redirect_to.use_route_names', true) ? route($afterCallback) : $afterCallback;
Other than the config variables, everything else can be left as is.
If the request is successful, the AccessTokenRetrieved
event is dispatched. It accepts the following values:
- The response JSON array comprised of:
access_token
,token_type
,expires_in
,refresh_token
- A Carbon representing the current date time, which is used (in conjunction with
expires_in
) to determine when theaccess_token
will expire
Create a listener for the event to interact with the data.
Important
Also, the controller uses a config (ynab-sdk-laravel.redirect_to.after_callback
), which is "home" by default.
The config (ynab-sdk-laravel.redirect_to.use_route_names
) dictates that the aformentioned config variable should be treated as a route name.
You may set it to false if you want to the literal route path.
If you make no changes, then the route name "home" is where the controller will be redirected to. If you do not register a route that is named "home" in your app, the controller will fail with a 500 error.
Once you have the access_token
, you can access the API the way you would with a personal access token:
use YnabSdkLaravel\YnabSdkLaravel\Ynab; $ynab = new Ynab('insert-access-token-here');
Be wary that your access_token
has an expiration date (i.e., expires_in
). You may track when your token is expiring and then use refresh_token
to reset your access_token
without the user having to authenticate on YNAB again.
Refresh Route
Registering the Route
When you place Route::ynabSdkLaravelOauth();
in your routes file, you also expose the refresh route. By default, the url should look like this: https://your-site.com/ynab-oauth/refresh
.
This is, of course, configurable (see: Callback Route Registration).
Accessing the Controller
The controller accepts a refresh_token
value and then calls YNAB to get a new access token given the information.
If successful, AccessTokenRetrieved
is dispatched to expose the new access_token
, expires_in
, and refresh_token
as well as the time retrieved so that you can determine when to refresh the token again.
When To Refresh The Token
The OauthHelper
class provides a handy method to calculate the time when the token expires.
use YnabSdkLaravel\YnabSdkLaravel\OauthHelper; // ... OauthHelper::getExpirationTimeOfAccessToken($dateRetrieved, $expiresIn);
The method takes the values which are exposed by the AccessTokenRetrieved
event that runs when initially retrieving or refreshing the access token.
Running Tests
To run tests, run the following command:
composer test
You may run tests with coverage:
composer test-coverage
Changelog
Please see CHANGELOG for more information on what has changed recently.
Contributing
Please see CONTRIBUTING for details.
Security Vulnerabilities
Please review our security policy on how to report security vulnerabilities.
Credits
License
The MIT License (MIT). Please see License File for more information.