Authentication

Give me access!

Introduction

Applications connect to Visma eAccounting API using OAuth2, the standard used by most APIs for authenticating and authorizing users. The following documentation will guide you how to authorize your application to act on behalf of a user (also referred to as the resource owner).

The OAuth2 flow is generally initiated by a user clicking a “Connect with Visma eAccounting” button in your application (web application, mobile app or desktop application). The end result of the OAuth2 flow is a token your application will use to access protected resources in Visma eAccounting on behalf of the user. The token is unique to each application/user combination.

New to OAuth2, or want to sharpen your skills? Here's some help, go either with the beginner version or go hardcore.

Scopes

You need to provide a list of requested scopes in the authentication request. API endpoints are related to a scope, eg. sales related endpoints requires the sales scope.

ScopeAccessDescription
ea:apirequiredMust be used to get access to eAccounting API
offline_accessrequiredMust be used to be able to receive a refresh token
ea:salesoptionalFull access to sales resources
ea:sales_readonlyoptionalRead-only access to sales resources
ea:accountingoptionalFull access to accounting resources
ea:accounting_readonlyoptionalRead-only access to accounting resources
ea:purchaseoptionalFull access to purchase resources
ea:purchase_readonlyoptionalRead-only access to purchase resources

The Server-side Flow

1. User Authentication

When the user clicks a “Connect with Visma eAccounting” button in your application, your application should make a request towards our authorization endpoint. In that request you need to provide client id, redirect uri, scopes, state, response type and the login prompt.

Parameter NameRequiredDescription
client_idrequired Provided to you upon registration for the Visma Partner Programme
redirect_urirequired Callback uri that you have registered upon registration for the Visma Partner Programme
scoperequired Permissions to request, see below for more information. If passing multiple scopes, separate them using %20 (URL-encoded space character) or + character
response_typerequired The grant type requested, for server-side flow it is always code
staterecommendedA unique string that is passed back upon completion. It should be used to avoid cross-site forgery attacks by passing in a value that’s unique to the user you’re authenticating and checking it when authorize completes
promptrecommendedSet select_account to ignore the standard company setting in Visma Online and always prompt the user with the selection of company. This is highly recommended.
This is available only in Production environment at the moment.
optionalSet prompt=login to force login. If you want the user to log in again (even if you're already logged in) to authenticate multiple times in different companies, for example.
These two prompt values can be used in combination with a + sign as a separator. The query will then look like this: prompt=login+select_account
acr_valuesrecommendedSet acr_values=service:44643EB1-3F76-4C1C-A672-402AE8085934 to show only the companies that have access to eAccounting in the company selector. Set forceselectcompany:true to ignore the standard company setting in Visma Online and always prompt the user with the selection of company. This will only work in combination with prompt=login. This is highly recommended. These two acr values can be used in combination with a + sign as a separator. The query will then look like this: acr_values=service:44643EB1-3F76-4C1C-A672-402AE8085934+forceselectcompany:true.
## Example on how the authentication request can look like

curl -X GET 'https://identity.vismaonline.com/connect/authorize?client_id=<client_id>&redirect_uri=<redirect_uri>&scope=ea:api%20offline_access%20ea:sales&state=<state_string>&response_type=code&prompt=select_account&acr_values=service:44643EB1-3F76-4C1C-A672-402AE8085934'

2. App Authorization & Redirect

Once Visma Authorization Server has successfully authenticated the user, the server will prompt them to authorize the application.

If the user clicks “Allow”, your application will be authorized. The Visma Authorization Server will redirect the user’s browser via HTTP 302 to the redirect_uri with an authorization code.

The authorization code is one time use and is valid for 5 minutes, in order to exchange it for access token and refresh token, which will be explained in the next section.

your-redirect-uri/?code=<authorization_code>

3. App Authentication

When you have recieved the authorization code, next step is to exchange that for a set of tokens. These tokens are needed in order to make authorized requests towards the authenticated eAccounting company.

Issue a post request like the example below. Note that the Authorization header in this request is client_id followed by a punctiuation sign : followed by client_secret. Then Base64 encode that string and provide, like in the example.

POST /connect/token HTTP/1.1
Authorization: Basic base64(client_id:client_secret)
Content-Type: application/x-www-form-urlencoded;charset=UTF-8

"grant_type=authorization_code&code=<authorization_code>&redirect_uri=<redirect_uri>"
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8

{
  "access_token": <access_token>,
  "refresh_token": <refresh_token>,
  "token_type":"bearer",
  "expires_in":3600
}

We recommend that you save all information in the response on your side, in order to make your integration as smooth as possible.

4. Using The Access Token

The access token is your way in to the API, and must be provided in all requests to the API. Since it's a bearer type of token, it should be provided as one aswell.

## This is a authorized request towards the API. The token is faked in this example.

curl -X GET -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6ImEzck1VZ01Gdjl0UGNsTGE2eUYzekFrZnF1RSIsImtpZCI6ImEzck1VZ01Gdjl0UGNsTGE2eUYzekFrZnF1RSJ9.eyJpc3MiOiJodHRwczovL2lkZW50aXR5LnZpc21hb25saW5lLmNvbSIsImF1ZCI6Imh0dHBzOi8vaWRlbnRpdHkudmlzbWFvbmxpbmUuY29tL3Jlc291cmNlcyIsImV4cCI6MTUwNzg4OTE5MiwibmJmIjoxNTA3ODg1NTkyLCJjbGllbnRfaWQiOiJjb2RlY2xpZW50Iiwic2NvcGUiOlsiZWE6c2FsZXMiLCJlYTpwdXJjaGFzZSIsImVhOmFjY291bnRpbmciLCJvZmZsaW5lX2FjY2VzcyIsImVhOmFwaSJdLCJzdWIiOiI2NjVhYzU5Yy0yNThiLTQzM2UtODA2Zi02MzkxZjU1MmFhOGEiLCJhdXRoX3RpbWUiOjE1MDc4ODU1NTQsImlkcCI6InZvbmlkc3J2IiwiY3VzdG9tZXJfaWQiOiI4ZDZhODZmZS1mN2IzLTRhZmUtOWQ5Mi1mNzY5OGJiMTJhZjAiLCJlbWFpbCI6ImFkbWluQHZpc21hb25saW5lLnNlIiwiYW1yIjpbImV4dGVybmFsIl19.LIIRPjwtDEtCYD1Sz2jlKDX9MClLDDXYSyfhjPKyGxOfXzBzfgNHfFmp6fa9AZ7RJZ9QFtbQ0vFj_QJgsWia6jJp_-is1LX_1cqB9G3XxbOuzJuIAVtd9gRgT16OVJ_vmwnll2mF2HD0XcYkJ5oppogF9CGJ3LY-stC8HaPkrW8eYEQ5vrJJjhC7RExVW_HXWRnb_mams7bK3lx2odFzCRglHXMNOgSgnbW0oOWRPCmWoP5_RY59t_9xB3GQ5hFQ5IxvVITJomr_uSk8iqF1m3aJn5oGfXjxH-63-0tVXEbnBtci-n15VG3K-Wh2Wbo_OWe434N9Euz-uXMJSCPgDg" \
'https://eaccountingapi.vismaonline.com/v2/companysettings'

60 minutes after the Access Token was issued, it will expire. In the next section we will go through how to refresh it using the refresh token.

5. Using The Refresh Token

When the Access Token has expired, it's time to make sure you have a new before next request in order to prevent unauthorized requests.

The request needed in this case is quite similar to the app authentication request but with a few modifications.

Change grant_type value to refresh_token. Also provide a property called refresh_token instead of code. The value of the refresh_token property is the refresh token itself. The response properties are identical to the previous request.

POST /connect/token HTTP/1.1
Authorization: Basic base64(client_id:client_secret)
Content-Type: application/x-www-form-urlencoded;charset=UTF-8

"grant_type=refresh_token&refresh_token=<refresh_token>"
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8

{
  "access_token": <access_token>,
  "refresh_token": <refresh_token>,
  "token_type":"bearer",
  "expires_in":3600
}

6. Token Revocation

If you would like to revoke a issued Refresh Token, you can use the Revocation endpoint. The provided Token will be invalidated for further use.

The Authorization towards this enpoint is the same as in the App Authentication request, client_id followed by a punctiuation sign : followed by client_secret. Then Base64 encode that string and provide in the request.

The request body contains two properties, token and token_type_hint. Token is required, but token_type_hint isn't. If token_type_hint isn't provided, the IdentityServer will try to figure out if it's a Access Token or Refresh Token. In the example below, I choose to let the IdentityServer know that it's a Refresh Token I would like to revoke.

POST /connect/revocation HTTP/1.1
Authorization: Basic base64(client_id:client_secret)
Content-Type: application/x-www-form-urlencoded;charset=UTF-8

"token=<refresh_token>&token_type_hint=refresh_token"

If successful, you will get a blank response with status code 200 OK.

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8

🚧

Refresh tokens are not static values

Note that refresh tokens change aswell as the access tokens, which makes it very important for you to save both access tokens and refresh tokens on your side, in order to make authorized requests and to refresh tokens in a correct way.