Onboard Standard accounts
A Quaderno Connect Standard Account is for users who have a direct relationship with Quaderno. This means your users can log in to their own dashboards, manage their accounts independently, and connect or disconnect their accounts from your platform whenever they choose.
Using OAuth is the most secure and efficient way to connect to these accounts. It allows your platform to securely obtain an access token for a user's Quaderno account without ever needing to see their password.
Here's why using the OAuth flow is the best approach:
- It's Secure: Users grant you access to their account through a trusted process, keeping their login credentials safe.
- It's Fast: You just need to send your user to a single link. They handle the rest—signing in, approving access—and we send them right back to you with the necessary authorization code.
- It's Future-Proof: As the Quaderno API evolves, you'll be able to access new features without needing to update your core authentication process.
The OAuth integration process
The integration process consists of four main steps, which we'll explore in detail below.
Step 1: Create an App
Before you can integrate, you'll need to create an app in the Quaderno system. This app represents your platform and provides the necessary credentials for the OAuth flow.
- Log in to your Quaderno account and create a new app.
- Provide a unique name for your app.
- Add your website URL and support email.
- Specify a publicly accessible Callback URL on your server. This is the endpoint where users will be redirected after they approve or deny the connection.
Once created, you'll be issued a unique Client ID and a Client Secret. Keep these secure, as you'll use them to identify your application throughout the OAuth flow.
Step 2: Generate the OAuth link
With your Client ID and Callback URL, you can create the OAuth link that your users will click to start the connection process. We recommend placing this link behind a button like "Connect with Quaderno."
Your link should follow this format:
https://sandbox-quadernoapp.com/oauth/authorize?client_id={{YOUR_CLIENT_ID}}
&redirect_uri={{YOUR_URL_ENCODED_CALLBACK_URL}}
&response_type=code
&scope=read_write
&state={{OPTIONAL_CSRF_TOKEN}}
// Optional parameters to pre-fill user information for new accounts
&business_name={{OPTIONAL_BUSINESS_NAME}}
&user_first_name={{OPTIONAL_USER_FIRST_NAME}}
&user_last_name={{OPTIONAL_USER_LAST_NAME}}
&user_email={{OPTIONAL_USER_EMAIL}}
&street={{OPTIONAL_STREET}}
&city={{OPTIONAL_CITY}}
®ion={{OPTIONAL_REGION}}
&postal_code={{OPTIONAL_POSTAL_CODE}}
&country={{OPTIONAL_COUNTRY}}
&default_tax_code={{OPTIONAL_DEFAULT_TAX_CODE}}
&default_product_type={{OPTIONAL_DEFAULT_PRODUCT_TYPE}}
Here's a breakdown of the key parameters:
Parameter | Description | Required |
---|---|---|
client_id | Your app's unique Client ID. | ✓ |
redirect_uri | The URL-encoded Callback URL on your server where Quaderno will send the user after authorization. | ✓ |
response_type | Always set this to code to initiate the authorization code flow. | ✓ |
scope | The level of access you need. Use read_write to be able to create transactions on behalf of your users. The default is read_only . | |
state | An optional value that will be returned to you in the callback. We highly recommend using this for a CSRF token to prevent cross-site request forgery attacks. | |
business_name , user_first_name , user_last_name , user_email , street , city , region , postal_code , country , default_tax_code , default_product_type | Optional parameters to pre-fill the account creation form for your user. These values will be used if the user does not have an existing Quaderno account. |
Possible values for default_tax_code
are: eservice
, ebook
, saas
, consulting
, standard
, reduced
, exempt
. Defaults to eservice
.
Possible values for default_product_type
are: good
and service
. Defaults to service
.
Step 3: Handle the callback
After a user clicks the link and authorizes your app, they will be redirected back to the Callback URL you provided.
On a successful connection, you will receive a URL with a temporal code
parameter:
{{APP_CALLBACK_URL}}?code=ca159b06d86757dbcae2e6950faf8fb2e9e7f596574a1df3f7294cf26a1f9e02&state={{OPTIONAL_CSRF_TOKEN}}
This code
is short-lived and can only be used once.
If the user denies access, the URL will contain an error
parameter instead:
{{APP_CALLBACK_URL}}?error=access_denied&error_description=The+resource+owner+or+authorization+server+denied+the+request.
Your application should be prepared to handle both success and error responses.
Step 4: Exchange the code for permanent tokens
The final step is to exchange the temporal code
for the permanent access_token
and refresh_token
. This must be done on your server to keep your Client Secret secure.
Send a POST
request to Quaderno's /oauth/token
endpoint.
curl https://sandbox-quadernoapp.com/oauth/token \
-u {{YOUR_CLIENT_ID}}:{{YOUR_SECRET_KEY}} \
-d code={{OAUTH_AUTHORIZATION_CODE}} \
-d redirect_uri={{YOUR_URL_ENCODED_CALLBACK_URL}} \
-d grant_type=authorization_code
Quaderno will respond with the user's account information and tokens:
{
"token_type": "bearer",
"account_id": "{ACCOUNT_ID}",
"refresh_token": "{REFRESH_TOKEN}",
"access_token": "{ACCESS_TOKEN}"
}
It is critical that you securely store the account_id
, access_token
, and refresh_token
in your database.
The access_token
is what you will use for all API calls on behalf of the user, while the refresh_token
will allow you to get new access tokens when the old one expires.
Post-integration tasks
Making API calls
Once you have the user's access_token
, you can make API calls on their behalf by including an Authorization: Bearer {{access_token}}
header with each request.
curl https://sandbox-quadernoapp.com/api/tax_rates/calculate?to_country=US&to_postal_code=90210&tax_code=eservice \
-H "Authorization: Bearer {{ACCESS_TOKEN}}"
Refreshing tokens
For security, an access_token
expires every 25 days. Your integration is responsible for refreshing it before it expires. Fortunately, the refresh_token
does not expire.
Use the refresh_token
to get a new access_token
with this POST
request:
curl https://sandbox-quadernoapp.com/oauth/token \
-u {{YOUR_CLIENT_ID}}:{{YOUR_SECRET_KEY}} \
-d refresh_token={{YOUR_REFRESH_TOKEN}} \
-d grant_type=refresh_token
Revoking access
To disconnect an account, send a POST
request to the /oauth/revoke
endpoint with the relevant tokens.
curl https://sandbox-quadernoapp.com/oauth/revoke \
-u {{YOUR_CLIENT_ID}}:{{YOUR_SECRET_KEY}} \
-d token={{ACCESS_TOKEN}}
A successful revocation returns a 200 OK
status with an empty body.