Skip to main content

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.

  1. Log in to your Quaderno account and create a new app.
  2. Provide a unique name for your app.
  3. Add your website URL and support email.
  4. 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.

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}}
&region={{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:

ParameterDescriptionRequired
client_idYour app's unique Client ID.
redirect_uriThe URL-encoded Callback URL on your server where Quaderno will send the user after authorization.
response_typeAlways set this to code to initiate the authorization code flow.
scopeThe level of access you need. Use read_write to be able to create transactions on behalf of your users. The default is read_only.
stateAn 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_typeOptional 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.
info

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}}
info

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.