Vanilla Code
Before starting to read this page, we invite you to check if this is the best authentication method for you. Please check the flowchart you can find on the Authentication page before proceeding.
The OAuth 2.0 Authorization Code Flow is the recommended method to retrieve an Access Token for applications that have access to secure, private storage such as web applications deployed on a server; if your use case isn't compatible with this requirement, we suggest checking the Authentication page to check the other methods supported by our app.
This guide describes our implementation of the OAuth 2.0 Authorization Code Flow. If you are interested in a more general explanation of this concept, please refer to the dedicated page.
To interact with our API on behalf of the user using this flow, it is necessary to implement the steps explained below.
In this guide, we'll try to keep our code examples as vanilla as possible, but we also added specific OAuth helpers to our SDKs to make the authorization implementation painless. If possible, we strongly suggest to use them.
Additionally, some open-source OAuth 2.0 libraries are available for each programming language. Those libraries take care of some of the following steps for you, so feel free to choose the one that you prefer to help you with the OAuth implementation.
In the last section of this page, you can find a non-exhaustive list of the available frameworks for each of the programming languages, but some others may be available.
🔑 Token types
Here's a quick reminder of the three tokens that we'll obtain in the following steps. All of the three tokens are pseudo casual strings with a specific prefix that can be used to discern each one of the tokens; each one of the tokens has a specific purpose and a lifespan (e.g. an expiration time) that define their validity.
Token Name | Description | Prefix | Lifespan |
---|---|---|---|
Authorization Code | This is the token you will exchange to get an Access Token. It is valid only one time and has a very short lifespan. | c/ | 60 seconds (from its emission) |
Access Token | This is the token you will use to make requests. | a/ | 24 hours (from its emission) |
Refresh Token | This is the token you will use only to make refresh requests to obtain a new Access Token when the old one expires, without having to ask the user to give a new explicit authorization. When it expires it is necessary to perform this flow again from step 1. | r/ | 1 year (from the last refresh request) |
0️⃣ Prerequisites: Create an app and retrieve the credentials
The Authorization Code Flow requires specific credentials, that are specific to a single application. You can create an app following this guide: Create an app.
While creating the app, you need to select the OAuth 2.0 authentication and authorization method and retrieve the Client ID and Client Secret credentials: you will need them in the following steps.
The Client Secret, used in the OAuth 2.0 flow, is a piece of sensible information so it must NEVER be shared with third-party actors, and it must always be kept safe (for example in an environment variable used by your backend). Never share it with other people, or publish it on your frontend! If it happened, then we suggest you to delete your application on the Fatture in Cloud page.
On the same page, you need to define a Redirect URL: it is an endpoint that must be exposed by your application to be able to receive the Authorization Code.
For this chapter, we will use the https://www.yourapplication.com/redirect URL, but you are free to specify one that best fits your needs.
The Redirect URI must be formally valid, and it will be checked while creating the application. For local development purposes, also the localhost URI is enabled (for example, you can declare "http://localhost:8080" to reach your backend running locally).
1️⃣ Redirect the user to the Fatture in Cloud authorization page
An external application can consume our API resources only if the owner gives permission to do it. The permissions can be obtained on a dedicated page published by Fatture in Cloud.
To perform this step, you just need to redirect the user to a specific URL; this URL will contain some specific information that must be collected beforehand:
Parameter name | Description |
---|---|
response_type | Must be set to "code". This indicates that you are requesting an authorization code. |
client_id | Your Client ID, e.g. the identifier of your app. You can find it on your Fatture in Cloud application page (see the previous step). |
redirect_uri | The URL to which you want to redirect the user after completing the authorization process. Note that this must be the same that you provided while creating the app. |
scope | A space-separated list of permissions you are asking for your app. See the Scopes page for further information. |
state | A custom, request-specific string parameter generated by your application, that can be double-checked in the next step (see the following note). |
The state parameter is intended to preserve some state object set by the client in the Authorization request, and make it available to the client in the response. The main security reason for this is to stop Cross Site Request Forgery (XSRF). XSRF attacks are not new or specific to OAuth, and the way to prevent them is to include something in the request that the client can verify in the response but that an attacker could not know. An example of this would be a hash of the session cookie or a random value stored in the server linked to the session. If the client can’t verify the value returned, then it must reject authentication responses that could be generated as the result of requests by third-party attackers. Also, if you need to keep any other pieces of information you can encode it in the state parameter as well since it is just a string.
Below you can see some vanilla code examples that will help you build the URL for the redirect.
- C#
- Go
- Java
- JavaScript
- PHP
- Python
- Ruby
- TypeScript
var baseUrl = "https://api-v2.fattureincloud.it";
var authorizePath = "/oauth/authorize";
var redirectUrl = "https://www.yourapplication.com/redirect"; // the endpoint you exposed
var clientId = "CLIENT_ID"; // your client id
var scopes = "scope:r scope:a"; // space separed list of scopes
var state = "EXAMPLE_STATE"; // a state generated by your application for this specific request
var query = System.Web.HttpUtility.ParseQueryString(string.Empty);
query.Add("response_type", "code");
query.Add("client_id", clientId);
query.Add("redirect_uri", redirectUrl);
query.Add("scope", scopes);
query.Add("state", state);
var authorizeUrl = baseUrl + authorizePath + '?' + query; // the url to be used
baseUrl := "https://api-v2.fattureincloud.it"
authorizePath := "/oauth/authorize"
redirectUrl := "https://www.yourapplication.com/redirect" // the endpoint you exposed
clientId := "CLIENT_ID" // your client id
scopes := "scope:r scope:a" // space separed list of scopes
state := "EXAMPLE_STATE" // a state generated by your application for this specific request
params := url.Values{}
params.Add("response_type", "code")
params.Add("client_id", clientId)
params.Add("redirect_uri", redirectUrl)
params.Add("scope", scopes)
params.Add("state", state)
query := params.Encode() // url-encoded query string
authorizeUrl := baseUrl + authorizePath + "?" + query // the url to be used
import java.net.URL;
String baseUrl = "api-v2.fattureincloud.it";
String authorizePath = "/oauth/authorize";
String redirectUrl = "https://www.yourapplication.com/redirect"; // the endpoint you exposed
String clientId = "CLIENT_ID"; // your client id
String scopes = "scope:r scope:a"; // space separed list of scopes
String state = "EXAMPLE_STATE"; // a state generated by your application for this specific request
URL url = new HttpUrl.Builder()
.scheme("https")
.host(baseUrl)
.addPathSegments(authorizePath)
.addQueryParameter("response_type", "code")
.addQueryParameter("client_id", clientId)
.addQueryParameter("redirect_uri", redirectUri)
.addQueryParameter("scope", scopes)
.addQueryParameter("state", state)
.build().url();
String authorizeUrl = url.toString();
var baseUrl = "https://api-v2.fattureincloud.it";
var authorizePath = "/oauth/authorize";
var redirectUrl = "https://www.yourapplication.com/redirect"; // the endpoint you exposed
var clientId = "CLIENT_ID"; // your client id
var scopes = "scope:r scope:a"; // space separed list of scopes
var state = "EXAMPLE_STATE"; // a state generated by your application for this specific request
var params = {
response_type: "code",
client_id: clientId,
redirect_uri: redirectUrl,
scope: scopes,
state: state,
};
var query = new URLSearchParams(params).toString(); // url-encoded query string
var authorizeUrl = baseUrl + authorizePath + "?" + query; // the url to be used
$baseUrl = 'https://api-v2.fattureincloud.it';
$authorizePath = '/oauth/authorize';
$redirectUrl = 'https://www.yourapplication.com/redirect'; // the endpoint you exposed
$clientId = 'CLIENT_ID'; // your client id
$scopes = 'scope:r scope:a'; // space separed list of scopes
$state = 'EXAMPLE_STATE'; // a state generated by your application for this specific request
$params = array(
'response_type' => 'code',
'client_id' => $clientId,
'redirect_uri' => $redirectUrl,
'scope' => $scopes,
'state' => $state,
);
$query = http_build_query($params); // url-encoded query string
$authorizeUrl = $baseUrl . $authorizePath . '?' . $query; // the url to be used
import requests
from urllib.parse import urlencode
base_url = 'https://api-v2.fattureincloud.it'
authorize_path = '/oauth/authorize'
redirect_url = 'https://www.yourapplication.com/redirect' # the endpoint you exposed
client_id = 'CLIENT_ID' # your client id
scopes = 'scope:r scope:a' # space separed list of scopes
state = 'EXAMPLE_STATE' # a state generated by your application for this specific request
params = {
'response_type': 'code',
'client_id': client_id,
'redirect_uri': redirect_url,
'scope': scopes,
'state': state
}
query = urlencode(params)
authorize_url = base_url + authorize_path + "?" + query # the url to be used
require 'uri'
base_url = 'https://api-v2.fattureincloud.it'
authorize_path = '/oauth/authorize'
redirect_url = 'https://www.yourapplication.com/redirect' # the endpoint you exposed
client_id = 'CLIENT_ID' # your client id
scopes = 'scope:r scope:a' # space separed list of scopes
state = 'EXAMPLE_STATE' # a state generated by your application for this specific request
params = {
'response_type': 'code',
'client_id': client_id,
'redirect_uri': redirect_url,
'scope': scopes,
'state': state
}
authorize_url = base_url + authorize_path # the url to be used
uri = URI(authorize_url)
uri.query = URI.encode_www_form(params) # url-encoded query string
const baseUrl = "https://api-v2.fattureincloud.it";
const authorizePath = "/oauth/authorize";
const redirectUrl = "https://www.yourapplication.com/redirect"; // the endpoint you exposed
const clientId = "CLIENT_ID"; // your client id
const scopes = "scope:r scope:a"; // space separed list of scopes
const state = "EXAMPLE_STATE"; // a state generated by your application for this specific request
const params = {
response_type: "code",
client_id: clientId,
redirect_uri: redirectUrl,
scope: scopes,
state: state,
};
const query = new URLSearchParams(params).toString(); // url-encoded query string
const authorizeUrl = baseUrl + authorizePath + "?" + query; // the url to be used
The generated URL, with URL-encoded params, will look like this:
https://api-v2.fattureincloud.it/oauth/authorize?response_type=code&client_id=CLIENT_ID&redirect_uri=https%3A%2F%2Fwww.yourapplication.com%2Fredirect&scope=scope%3Ar%20scope%3Aa&state=EXAMPLE_STATE
This is not a simple HTTP GET request, you need to be able to open a browser page to complete this step.
Once the URL is generated, you must use it to redirect the user. Once landed on the Fatture in Cloud page, the user will be required to:
- Login to Fatture in Cloud using his account credentials;
- Give explicit consent to the permissions requested by the application. These operations will be performed automatically by our page, so you don't need to worry about them.
Please note that the permissions requested to the user on our page will be strictly related to the scopes you picked and inserted in the query string.
It is important to select the minimum set of scopes required by your application to fulfill your use case: if you select too few, you may obtain some 403 Forbidden errors while performing operations out of the scope set, while if you select too many the user could feel overwhelmed and reject your permissions request entirely.
2️⃣ Obtain the Authorization Code
Once the user gave explicit consent to your request, our page will redirect the user to the Redirect URL specified in the previous step (in the example, to https://www.yourapplication.com/redirect).
Our page will share two parameters with your application:
Parameter name | Description |
---|---|
state | The state string, as provided in the previous step. |
code | The Authorization Code token. |
The two parameters will be sent to your application as URL-encoded query string parameters, so your application must be able to manage appropriately the following HTTP GET request (in this example, we use "AUTH_CODE" as value for the returned Authorization Code):
GET https://www.yourapplication.com/redirect?state=EXAMPLE_STATE&code=c%2FeyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJDRENzRVlGaE5YZ0NkWDhldW1GRnVxcllIUDdYTTk2dyIsImV4cCI6MTU4OTQ2NjYzNn0.v9yyzsdC50mRF8gue46WjXqO2ADfSPZH9SZc-QTHO54
Most frameworks take care of extracting the query string params for you. In case you need to extract the params from the URL on your own, you can use the following code:
- C#
- Go
- Java
- JavaScript
- PHP
- Python
- Ruby
- TypeScript
// in this example we define the var url as string, but it should come from the HTTP request
var url = new Uri("https://www.yourapplication.com/redirect?state=EXAMPLE_STATE&code=c%2FeyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJDRENzRVlGaE5YZ0NkWDhldW1GRnVxcllIUDdYTTk2dyIsImV4cCI6MTU4OTQ2NjYzNn0.v9yyzsdC50mRF8gue46WjXqO2ADfSPZH9SZc-QTHO54");
var state = System.Web.HttpUtility.ParseQueryString(url.Query).Get("state");
var code = System.Web.HttpUtility.ParseQueryString(url.Query).Get("code");
// in this example we define the var url as string, but it should come from the HTTP request
uri, _ := url.Parse("https://www.yourapplication.com/redirect?state=EXAMPLE_STATE&code=c%2FeyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJDRENzRVlGaE5YZ0NkWDhldW1GRnVxcllIUDdYTTk2dyIsImV4cCI6MTU4OTQ2NjYzNn0.v9yyzsdC50mRF8gue46WjXqO2ADfSPZH9SZc-QTHO54")
queryParams := uri.Query()
state := queryParams.Get("state")
code := queryParams.Get("code")
// in this example we define the var url as string, but it should come from the HTTP request
URI uri = new Uri("https://www.yourapplication.com/redirect?code=c%2FeyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJDRENzRVlGaE5YZ0NkWDhldW1GRnVxcllIUDdYTTk2dyIsImV4cCI6MTU4OTQ2NjYzNn0.v9yyzsdC50mRF8gue46WjXqO2ADfSPZH9SZc-QTHO54&state=EXAMPLE_STATE");
String query = exchuri.getQuery();
if(query == null) {
query = ""
};
if(query.contains("code")){
int start = query.indexOf("code=") + 5;
int finish = query.indexOf("&");
String code = query.substring(start, finish);
}
if(query.contains("state")){
int start = query.indexOf("state=") + 6;
String state = query.substring(start);
}
// in this example we define the var url param as string, but it should come from the HTTP request
var url =
"https://www.yourapplication.com/redirect?state=EXAMPLE_STATE&code=c%2FeyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJDRENzRVlGaE5YZ0NkWDhldW1GRnVxcllIUDdYTTk2dyIsImV4cCI6MTU4OTQ2NjYzNn0.v9yyzsdC50mRF8gue46WjXqO2ADfSPZH9SZc-QTHO54";
var urlObj = URL(url);
var state = urlObj.searchParams.get("state");
var code = urlObj.searchParams.get("code");
// in this example we define the $url param as string, but it should come from the HTTP request
$url = 'https://www.yourapplication.com/redirect?state=EXAMPLE_STATE&code=c%2FeyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJDRENzRVlGaE5YZ0NkWDhldW1GRnVxcllIUDdYTTk2dyIsImV4cCI6MTU4OTQ2NjYzNn0.v9yyzsdC50mRF8gue46WjXqO2ADfSPZH9SZc-QTHO54';
$query = parse_url($url, PHP_URL_QUERY);
parse_str($query, $params);
$state = $params['state'];
$code = $params['code'];
# in this example we define the var url as string, but it should come from the HTTP request
from urllib.parse import urlparse
from urllib.parse import parse_qs
url = 'https://www.yourapplication.com/redirect?state=EXAMPLE_STATE&code=c%2FeyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJDRENzRVlGaE5YZ0NkWDhldW1GRnVxcllIUDdYTTk2dyIsImV4cCI6MTU4OTQ2NjYzNn0.v9yyzsdC50mRF8gue46WjXqO2ADfSPZH9SZc-QTHO54'
parsed_url = urlparse(url)
state = parse_qs(parsed_url.query)['state'][0]
code = parse_qs(parsed_url.query)['code'][0]
require 'uri'
# in this example we define the var url as string, but it should come from the HTTP request
uri = URI('https://www.yourapplication.com/redirect?state=EXAMPLE_STATE&code=c%2FeyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJDRENzRVlGaE5YZ0NkWDhldW1GRnVxcllIUDdYTTk2dyIsImV4cCI6MTU4OTQ2NjYzNn0.v9yyzsdC50mRF8gue46WjXqO2ADfSPZH9SZc-QTHO54')
url_obj = URI::decode_www_form(uri.query).to_h
state = url_obj["state"]
code = url_obj["code"]
// in this example we define the var url param as string, but it should come from the HTTP request
const url =
"https://www.yourapplication.com/redirect?state=EXAMPLE_STATE&code=c%2FeyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJDRENzRVlGaE5YZ0NkWDhldW1GRnVxcllIUDdYTTk2dyIsImV4cCI6MTU4OTQ2NjYzNn0.v9yyzsdC50mRF8gue46WjXqO2ADfSPZH9SZc-QTHO54";
const urlObj = new URL(url);
const state = urlObj.searchParams.get("state");
const code = urlObj.searchParams.get("code");
Once you extracted the two parameters, you must check the state parameter value; if it doesn’t match, then probably a third party created the request, and you should abort the process.
If the state is valid, then you can use the code parameter to perform the next step.
3️⃣ Obtain the Access Token
The Authorization Code obtained above has only one purpose: to exchange it with an Access Token.
Once you checked that the state is valid, you can use it to retrieve the token with a POST HTTP call to the https://api-v2.fattureincloud.it/oauth/token endpoint.
The parameters required for the request are the following:
Parameter name | Description |
---|---|
grant_type | Must be set to "authorization_code". This indicates that you want to exchange an Authorization Code for an Access Token. |
client_id | Your Client ID, e.g. the identifier of your app. You can find it on your Fatture in Cloud application page (see the previous step). |
client_secret | Your Client Secret, e.g. the secret of your app. You can find it on your Fatture in Cloud application page (see the previous step). |
redirect_uri | The same redirect URL defined previously. |
code | The Authorization Code obtained in the previous step. |
It is important to keep the Client Secret a secret. So it must be stored carefully and it should be used only in backend applications. Don't commit it to public repositories and don't use it where the users could obtain it (for example in frontend applications).
We perform a String Equals to compare the Redirect URI you will send in the following request and the one you inserted in the Application page, so they must be exactly the same. This means that if the two paths are equivalent but the strings are different (for example, because you added a "/" at the end of only one of the two strings) you will still obtain an error.
Also, if you use different applications for your different environments (for example, DEV and PROD), please use the correct Redirect URI for the environment you're currently in: if the two redirect URIs are different and you're using the DEV redirect URI while running in PROD env, you'll obtain an error.
The cURL command will look like this:
- cURL
- HTTP
curl --request POST \
--url https://api-v2.fattureincloud.it/oauth/token \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data '
{
"grant_type": "authorization_code",
"client_id": "CLIENT_ID",
"client_secret": "CLIENT_SECRET",
"redirect_uri": "https://www.yourapplication.com/redirect",
"code": "c/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJDRENzRVlGaE5YZ0NkWDhldW1GRnVxcllIUDdYTTk2dyIsImV4cCI6MTU4OTQ2NjYzNn0.v9yyzsdC50mRF8gue46WjXqO2ADfSPZH9SZc-QTHO54"
}
'
POST /oauth/token HTTP/1.1
Host: api-v2.fattureincloud.it
Accept: application/json
Content-Type: application/json
Content-Length: 344
{
"grant_type": "authorization_code",
"client_id": "CLIENT_ID",
"client_secret": "CLIENT_SECRET",
"redirect_uri": "https://www.yourapplication.com/redirect",
"code": "c/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJDRENzRVlGaE5YZ0NkWDhldW1GRnVxcllIUDdYTTk2dyIsImV4cCI6MTU4OTQ2NjYzNn0.v9yyzsdC50mRF8gue46WjXqO2ADfSPZH9SZc-QTHO54"
}
Below you can find some vanilla code examples implementing the same command.
- C#
- Go
- Java
- JavaScript
- PHP
- Python
- Ruby
- TypeScript
// this code uses RestSharp Client: https://restsharp.dev
// you can install it with the following command:
// dotnet add package RestSharp
using System;
using RestSharp;
namespace restclient
{
class Program
{
static void Main(string[] args)
{
// for this example we define the code as string, but you should have obtained it in the previous steps
var code = "c/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJDRENzRVlGaE5YZ0NkWDhldW1GRnVxcllIUDdYTTk2dyIsImV4cCI6MTU4OTQ2NjYzNn0.v9yyzsdC50mRF8gue46WjXqO2ADfSPZH9SZc-QTHO54";
var baseUrl = "https://api-v2.fattureincloud.it";
var tokenPath = "/oauth/token";
var redirectUrl = "https://www.yourapplication.com/redirect"; // the endpoint you exposed
var clientId = "CLIENT_ID"; // your client id
var clientSecret = "CLIENT_SECRET"; // your client secret
var params = new {
grant_type = "authorization_code",
client_id = clientId,
client_secret = clientSecret,
redirect_uri = redirectUrl,
code = code
};
var client = new RestClient(baseUrl + tokenPath);
var request = new RestRequest(Method.POST);
request.AddHeader("content-type", "application/json");
request.AddJsonBody(params);
IRestResponse response = client.Execute(request);
Console.Write(response.Content.ToString());
}
}
}
package main
import (
"bytes"
"encoding/json"
"io/ioutil"
"log"
"net/http"
)
func main() {
// in this example we define the code as string, but you should have obtained it in the previous steps
code := "c/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJDRENzRVlGaE5YZ0NkWDhldW1GRnVxcllIUDdYTTk2dyIsImV4cCI6MTU4OTQ2NjYzNn0.v9yyzsdC50mRF8gue46WjXqO2ADfSPZH9SZc-QTHO54"
baseUrl := "https://api-v2.fattureincloud.it"
tokenPath := "/oauth/token"
redirectUrl := "http://localhost:8000/oauth" // the endpoint you exposed
clientId := "CLIENT_ID" // your client id
clientSecret := "CLIENT_SECRET" // your client secret
params := map[string]string{
"grant_type": "authorization_code",
"client_id": clientId,
"client_secret": clientSecret,
"redirect_uri": redirectUrl,
"code": code,
}
reqBody, _ := json.Marshal(params)
resp, err := http.Post(baseUrl+tokenPath, "application/json", bytes.NewBuffer(reqBody))
if err != nil {
log.Println("Error on response.\n[ERROR] -", err)
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Println("Error while reading the response bytes:", err)
}
log.Println(string([]byte(body)))
}
// this code uses OkHttpClient
import okhttp3.*;
import java.io.IOException;
import java.net.URL;
public class Application {
public static void main(String[] args) throws IOException {
// for this example we define the code as string, but you should have obtained it in the previous steps
String code = "c/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJDRENzRVlGaE5YZ0NkWDhldW1GRnVxcllIUDdYTTk2dyIsImV4cCI6MTU4OTQ2NjYzNn0.v9yyzsdC50mRF8gue46WjXqO2ADfSPZH9SZc-QTHO54";
String clientId = "CLIENT_ID"; // your client id
String clientSecret = "CLIENT_SECRET"; // your client secret
String redirectUri = "https://www.yourapplication.com/redirect"; // the endpoint you exposed
host = "api-v2.fattureincloud.it";
String accessTokenUri = "/oauth/token";
RequestBody formBody = new FormBody.Builder()
.add("grant_type", "authorization_code")
.add("client_id", clientId)
.add("client_secret", clientSecret)
.add("redirect_uri", redirectUri)
.add("code", code)
.build();
Request request = new Request.Builder()
.url("https://" + host + accessTokenUri)
.post(formBody)
.build();
OkHttpClient client = new OkHttpClient();
Call call = client.newCall(request);
Response response = call.execute();
System.out.println(response.body().string());
}
}
var http = require("https");
// for this example we define the code as string, but you should have obtained it in the previous steps
var code =
"c/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJDRENzRVlGaE5YZ0NkWDhldW1GRnVxcllIUDdYTTk2dyIsImV4cCI6MTU4OTQ2NjYzNn0.v9yyzsdC50mRF8gue46WjXqO2ADfSPZH9SZc-QTHO54";
var baseUrl = "https://api-v2.fattureincloud.it";
var tokenPath = "/oauth/token";
var redirectUrl = "https://www.yourapplication.com/redirect"; // the endpoint you exposed
var clientId = "CLIENT_ID"; // your client id
var clientSecret = "CLIENT_SECRET"; // your client secret
var params = {
grant_type: "authorization_code",
client_id: clientId,
client_secret: clientSecret,
redirect_uri: redirectUrl,
code: code,
};
var options = {
method: "POST",
hostname: baseUrl,
port: null,
path: tokenPath,
headers: {
"content-type": "application/json",
},
};
var req = http.request(options, function (res) {
var chunks = [];
res.on("data", function (chunk) {
chunks.push(chunk);
});
res.on("end", function () {
var body = Buffer.concat(chunks);
console.log(body.toString());
});
});
req.write(JSON.stringify(params));
req.end();
// this code uses Guzzle HTTP Client: https://docs.guzzlephp.org/en/stable/
// and also ext-json
// you can install them with the following command:
// composer require guzzlehttp/guzzle ext-json
use GuzzleHttp\Client;
use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Psr7;
// for this example we define the code as string, but you should have obtained it in the previous steps
$code = 'c/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJDRENzRVlGaE5YZ0NkWDhldW1GRnVxcllIUDdYTTk2dyIsImV4cCI6MTU4OTQ2NjYzNn0.v9yyzsdC50mRF8gue46WjXqO2ADfSPZH9SZc-QTHO54';
$client = new Client();
$baseUrl = 'https://api-v2.fattureincloud.it';
$tokenPath = '/oauth/token';
$redirectUrl = 'https://www.yourapplication.com/redirect'; // the endpoint you exposed
$clientId = 'CLIENT_ID'; // your client id
$clientSecret = 'CLIENT_SECRET'; // your client secret
$tokenUrl = $baseUrl . $tokenPath;
$params = [
'grant_type' => 'authorization_code',
'client_id' => $clientId,
'client_secret' => $clientSecret,
'redirect_uri' => $redirectUrl,
'code' => $code
];
try {
$response = $client->request('POST', $tokenUrl, [
'json' => $params
]);
return json_decode((string) $response->getBody());
} catch (ClientException $e) {
echo Psr7\Message::toString($e->getRequest());
echo Psr7\Message::toString($e->getResponse());
}
import requests
# for this example we define the code as string, but you should have obtained it in the previous steps
code = 'c/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJDRENzRVlGaE5YZ0NkWDhldW1GRnVxcllIUDdYTTk2dyIsImV4cCI6MTU4OTQ2NjYzNn0.v9yyzsdC50mRF8gue46WjXqO2ADfSPZH9SZc-QTHO54'
base_url = 'https://api-v2.fattureincloud.it'
token_path = '/oauth/token'
redirect_url = 'https://www.yourapplication.com/redirect' # the endpoint you exposed
client_id = 'CLIENT_ID' # your client id
client_secret = 'CLIENT_SECRET' # your client secret
params = {
'grant_type': 'authorization_code',
'client_id': client_id,
'client_secret': client_secret,
'redirect_uri': redirect_url,
'code': code
}
response = requests.post(base_url + token_path, data=params)
print(response.json())
require 'uri'
require 'net/http'
# for this example we define the code as string, but you should have obtained it in the previous steps
code = 'c/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJDRENzRVlGaE5YZ0NkWDhldW1GRnVxcllIUDdYTTk2dyIsImV4cCI6MTU4OTQ2NjYzNn0.v9yyzsdC50mRF8gue46WjXqO2ADfSPZH9SZc-QTHO54'
base_url = 'https://api-v2.fattureincloud.it'
token_path = '/oauth/token'
redirect_url = 'https://www.yourapplication.com/redirect' # the endpoint you exposed
client_id = 'CLIENT_ID' # your client id
client_secret = 'CLIENT_SECRET' # your client secret
params = {
grant_type: 'authorization_code',
client_id: client_id,
client_secret: client_secret,
redirect_uri: redirect_url,
code: code
}
uri = URI(base_url + token_path)
res = Net::HTTP.post_form(uri, params)
puts res.body
// in this example we are using the node-fetch library to make the request
import fetch, { Headers } from "node-fetch";
// for this example we define the code as string, but you should have obtained it in the previous steps
var code =
"c/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJDRENzRVlGaE5YZ0NkWDhldW1GRnVxcllIUDdYTTk2dyIsImV4cCI6MTU4OTQ2NjYzNn0.v9yyzsdC50mRF8gue46WjXqO2ADfSPZH9SZc-QTHO54";
var baseUrl = "https://api-v2.fattureincloud.it";
var tokenPath = "/oauth/token";
var redirectUrl = "https://www.yourapplication.com/redirect"; // the endpoint you exposed
var clientId = "CLIENT_ID"; // your client id
var clientSecret = "CLIENT_SECRET"; // your client secret
var params = {
grant_type: "authorization_code",
client_id: clientId,
client_secret: clientSecret,
redirect_uri: redirectUrl,
code: code,
};
var headers = new Headers({
"Content-Type": "application/json",
});
var options = {
method: "POST",
body: JSON.stringify(params),
headers: headers,
};
try {
var res = await fetch(baseUrl + tokenPath, options);
var json = await res.json();
console.log(json);
} catch (err) {
console.log(err);
}
The response body will be similar to the following:
{
"token_type": "bearer",
"access_token": "a/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJTQzJLSlRpTjVXTTBORFR0SWd2Y1o4cmhFR1ZrdmFjRiIsImV4cCI6MTU4OTY0MDk3M30.DNG4jX8Au3WMxVtb06RUNi0Dj5cDylagpZPgDLhpIhY",
"refresh_token": "r/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJxaDh4bXJMM0Y0SHExWU1RSDRhcHhWTVdDR2t0SktsdiJ9.IXEqUdfQjlR6EWas1QeCzpqd8O08usvJHaMYbjwVdWY",
"expires_in": 86400
}
The returned parameters are:
Parameter name | Description |
---|---|
token_type | Set as "bearer", it indicates how to use the returned token in the following REST calls. |
access_token | The Access Token. |
refresh_token | The Refresh Token. |
expires_in | The validity of the Access Token in seconds before its expiration. |
As you can see, the REST call will return the Access Token and the Refresh Token. The Access Token can be used to perform multiple API requests, but it expires after a certain amount of time. The Refresh Token instead can be used to obtain a new Access Token once the previous one is expired; it also expires, but its lifespan is higher than the Access Token one.
Now you can use the Access Token to interact with the Fatture in Cloud API. In the next section, you'll see how to use it to perform a request.
The Access Token (and by extension the Refresh Token) makes it possible to perform operations on the Fatture in Cloud API on behalf of the user, thus your application will be able to read and modify the user's own resources. This means that the tokens are a precious resource that must be protected (avoid sending them to the frontend).
Also, your application will obtain a dedicated token set for each one of the users, so it will be necessary to correctly associate a single user to his own tokens.
📃 Complete Helper
Here you can find all the code from the previous paragraphs put togheter in a single class.
- C#
- Go
- Java
- JavaScript
- PHP
- Python
- Ruby
- TypeScript
using RestSharp;
using System;
namespace OauthQuickstart.Helpers
{
public class FattureInCloudOauth2Provider
{
//============================================================================================================================================
/*
* Make sure you set the next properties according to your needs and use the
* credentials provided at the creation of your FattureInCloud app.
*/
// Replace with your redirect url (ex. http://localhost:5000/)
static string redirectUrl = "REDIRECT_URL";
// Replace with your client Id
static string clientId = "CLIENT_ID";
// Replace with your client Secret
static string clientSecret = "CLIENT_SECRET";
// Replace with the required scopes
static string scopes = "entity.suppliers:a";
//============================================================================================================================================
// The following properties and methods are needed for the oauth token management
// No need to edit anything
static string baseUrl = "https://api-v2.fattureincloud.it";
static string authorizePath = "/oauth/authorize";
static string tokenPath = "/oauth/token";
public static string GetAuthorizationUrl(string state)
{
var query = System.Web.HttpUtility.ParseQueryString(string.Empty);
query.Add("response_type", "code");
query.Add("client_id", clientId);
query.Add("redirect_uri", redirectUrl);
query.Add("scope", scopes);
query.Add("state", state);
string url = baseUrl + authorizePath + '?' + query; // the url to be used
return url;
}
public static string getAccessTokenUrl()
{
return baseUrl + tokenPath;
}
public static string getAccessToken(string code)
{
Object obj = new
{
grant_type = "authorization_code",
client_id = clientId,
client_secret = clientSecret,
redirect_uri = redirectUrl,
code = code
};
var client = new RestClient(baseUrl + tokenPath);
var request = new RestRequest(Method.POST);
request.AddHeader("content-type", "application/json");
request.AddJsonBody(obj);
IRestResponse response = client.Execute(request);
return(response.Content.ToString());
}
}
}
package oauthHelper
import (
"bytes"
"encoding/json"
"io/ioutil"
"log"
"net/http"
"net/url"
)
const (
//==============================================================================
/*
* Make sure you set the next properties according to your needs and use the
* credentials provided at the creation of your FattureInCloud app.
*/
// Replace with your client Id
clientId = "CLIENT_ID"
// Replace with your client Secret
clientSecret = "CLIENT_SECRET"
// Replace with your redirect url
redirectUri = "http://localhost:8000/oauth"
// Replace with the required scopes
scopes = "entity.suppliers:r"
// Replace with the wanted state
state = "state"
//==============================================================================
accessTokenUri = "https://api-v2.fattureincloud.it/oauth/token"
authorizationUri = "https://api-v2.fattureincloud.it/oauth/authorize"
)
// These methods are needed for the oauth token management
func getUri() string {
params := url.Values{}
params.Add("response_type", "code")
params.Add("client_id", clientId)
params.Add("redirect_uri", redirectUri)
params.Add("scope", scopes)
params.Add("state", state)
query := params.Encode()
return authorizationUri + "?" + query
}
func getToken(authCode string) string {
params := map[string]string{
"grant_type": "authorization_code",
"client_id": clientId,
"client_secret": clientSecret,
"redirect_uri": redirectUri,
"code": authCode,
}
reqBody, _ := json.Marshal(params)
resp, err := http.Post(accessTokenUri, "application/json", bytes.NewBuffer(reqBody))
if err != nil {
log.Println("Error on response.\n[ERROR] -", err)
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Println("Error while reading the response bytes:", err)
}
return string([]byte(body))
}
import okhttp3.*;
import java.io.IOException;
import java.net.URL;
public class FattureInCloudOauth2Provider {
//==============================================================================================================================================
/*
* Make sure you set the next properties according to your needs and use the credentials
* provided at the creation of your FattureInCloud app.
*/
// Replace with your client Id
static String clientId = "YOUR_CLIENT_ID";
// Replace with your client Secret
static String clientSecret = "YOUR_CLIENT_SECRET";
// Replace with your redirect url
static String redirectUri = "http://localhost:8000/oauth";
// Replace with the required scopes
static String scopes = "entity.suppliers:r";
// Replace with the wanted state
static String state = "state";
//==============================================================================================================================================
// The following properties and methods are needed for the oauth token management
// No need to edit anything
static String host = "api-v2.fattureincloud.it";
static String accessTokenUri = "/oauth/token";
static String authorizationUri = "oauth/authorize";
static String getUri(){
URL url = new HttpUrl.Builder()
.scheme("https")
.host(host)
.addPathSegments(authorizationUri)
.addQueryParameter("response_type", "code")
.addQueryParameter("client_id", clientId)
.addQueryParameter("redirect_uri", redirectUri)
.addQueryParameter("scope", scopes)
.addQueryParameter("state", state)
.build().url();
return url.toString();
}
static String getToken(String code) throws IOException {
RequestBody formBody = new FormBody.Builder()
.add("grant_type", "authorization_code")
.add("client_id", clientId)
.add("client_secret", clientSecret)
.add("redirect_uri", redirectUri)
.add("code", code)
.build();
Request request = new Request.Builder()
.url("https://" + host + accessTokenUri)
.post(formBody)
.build();
OkHttpClient client = new OkHttpClient();
Call call = client.newCall(request);
Response response = call.execute();
return response.body().string();
}
}
const axios = require("axios");
const fs = require("fs");
// This object contains the properties to retrieve the wanted properties
const fattureInCloudOauth = {
//==============================================================================================================================================
/*
* Make sure you set the next properties according to your needs and use the
* credentials provided at the creation of your FattureInCloud app.
*/
// Replace with your client Id
clientId: "CLIENT_ID",
// Replace with your client Secret
clientSecret: "CLIENT_SECRET",
// Replace with your redirect url
redirectUri: "http://localhost:8000/oauth.js",
// Replace with the required scopes
scopes: "entity.suppliers:r",
// Replace with the wanted state
state: "state",
//==============================================================================================================================================
accessTokenUri: "https://api-v2.fattureincloud.it/oauth/token",
authorizationUri: "https://api-v2.fattureincloud.it/oauth/authorize",
};
// These methods are needed for the oauth token management
function getUri() {
var params = {
response_type: "code",
client_id: fattureInCloudOauth.clientId,
redirect_uri: fattureInCloudOauth.redirectUri,
scope: fattureInCloudOauth.scopes,
state: fattureInCloudOauth.state,
};
var query = new URLSearchParams(params).toString();
var authorizeUrl = fattureInCloudOauth.authorizationUri + "?" + query;
return authorizeUrl;
}
async function getToken(authCode) {
const data = {
grant_type: "authorization_code",
client_id: fattureInCloudOauth.clientId,
client_secret: fattureInCloudOauth.clientSecret,
redirect_uri: fattureInCloudOauth.redirectUri,
code: authCode,
};
try {
var res = await axios.post(fattureInCloudOauth.accessTokenUri, data);
} catch (e) {
console.error(e);
}
if (res.status != 200) {
console.log(res.status);
}
return res.data;
}
module.exports = {
fattureInCloudOauth,
getUri,
getToken,
};
<?php
class FattureInCloudOauth2Provider
{
//============================================================================================================================================
/*
* Make sure you set the next properties according to your needs and use the credentials
* provided at the creation of your FattureInCloud app.
*/
// Replace with your redirect url (ex. http://localhost:8000/oauth.php)
public static $redirectUrl = 'http://localhost:8000/oauth.php';
// Replace with your client Id
public static $clientId = 'CLIENT_ID';
// Replace with your client Secret
public static $clientSecret = 'CLIENT_SECRET';
// Replace with the required scopes
public static $scopes = 'entity.suppliers:r';
//============================================================================================================================================
// The following properties and methods are needed for the oauth token management
// No need to edit anything
public static $baseUrl = 'https://api-v2.fattureincloud.it';
public static $authorizeUrl = '/oauth/authorize';
public static $tokenUrl = '/oauth/token';
public function getAuthorizationUrl($state)
{
$params = array(
'response_type' => 'code',
'client_id' => self::$clientId,
'redirect_uri' => self::$redirectUrl,
'scope' => self::$scopes,
'state' => $state
);
$query = http_build_query($params);
return self::$baseUrl . self::$authorizeUrl . '?' . $query;
}
function getAccessTokenUrl()
{
return self::$baseUrl . self::$tokenUrl;
}
public function getAccessToken($code) {
$params = [
'grant_type' => 'authorization_code',
'client_id' => self::$clientId,
'client_secret' => self::$clientSecret,
'redirect_uri' => self::$redirectUrl,
'code' => $code
];
$header = array("Content-Type: application/json");
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => $this->getAccessTokenUrl(),
CURLOPT_HTTPHEADER => $header,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($params)
));
$response = curl_exec($curl);
curl_close($curl);
if ($response === false) {
echo curl_error($curl);
}
return $response;
}
}
from urllib.parse import urlencode
import requests
class OauthHelper:
fatture_in_cloud_oauth = {
#==============================================================================================================================================
# Make sure you set the next properties according to your needs and use the
# credentials provided at the creation of your FattureInCloud app.
"client_id": "CLIENT_ID",
"client_secret": "CLIENT_SECRET",
"redirect_uri": "http://localhost:8000/oauth",
"scopes": "entity.suppliers:r",
"state": "state",
#==============================================================================================================================================
"access_token_uri": "https://api-v2.fattureincloud.it/oauth/token",
"authorization_uri": "https://api-v2.fattureincloud.it/oauth/authorize"
}
# these methods are needed for the OAuth token management
def get_uri():
params = {
'response_type': 'code',
'client_id': OauthHelper.fatture_in_cloud_oauth["client_id"],
'redirect_uri': OauthHelper.fatture_in_cloud_oauth["redirect_uri"],
'scope': OauthHelper.fatture_in_cloud_oauth["scopes"],
'state': OauthHelper.fatture_in_cloud_oauth["state"]
}
query = urlencode(params)
uri = OauthHelper.fatture_in_cloud_oauth["authorization_uri"] + "?" + query
return uri
def get_token(auth_code):
data = {
'grant_type': 'authorization_code',
'client_id': OauthHelper.fatture_in_cloud_oauth["client_id"],
'client_secret': OauthHelper.fatture_in_cloud_oauth["client_secret"],
'redirect_uri': OauthHelper.fatture_in_cloud_oauth["redirect_uri"],
'code': auth_code
}
res = requests.post(OauthHelper.fatture_in_cloud_oauth["access_token_uri"], data=data)
return res.json()
require 'uri'
require 'net/http'
class OauthHelper
#this object contains the properties to retrieve the wanted properties
@fatture_in_cloud_oauth = {
#==============================================================================================================================================
#Make sure you set the next properties according to your needs and using the credentials provided at the creation of your FattureInCloud app.
client_id: "CLIENT_ID",
client_secret: "CLIENT_ID",
redirect_uri: "http://localhost:8000/oauth",
scopes: "entity.suppliers:r",
state: "state",
#==============================================================================================================================================
access_token_uri: "https://api-v2.fattureincloud.it/oauth/token",
authorization_uri: "https://api-v2.fattureincloud.it/oauth/authorize"
}
#these methods are needed for the oauth token management
def self.get_uri()
params = {
response_type: 'code',
client_id: @fatture_in_cloud_oauth[:client_id],
redirect_uri: @fatture_in_cloud_oauth[:redirect_uri],
scope: @fatture_in_cloud_oauth[:scopes],
state: @fatture_in_cloud_oauth[:state]
}
uri = URI(@fatture_in_cloud_oauth[:authorization_uri])
uri.query = URI.encode_www_form(params)
return uri
end
def self.get_token(auth_code)
data = {
grant_type: "authorization_code",
client_id: @fatture_in_cloud_oauth[:client_id],
client_secret: @fatture_in_cloud_oauth[:client_secret],
redirect_uri: @fatture_in_cloud_oauth[:redirect_uri],
code: auth_code
}
uri = URI(@fatture_in_cloud_oauth[:access_token_uri])
res = Net::HTTP.post_form(uri, data)
return res.body
end
end
import axios from "axios";
// This object contains the properties to retrieve the wanted properties
export const fattureInCloudOauth = {
//==============================================================================================================================================
/*
* Make sure you set the next properties according to your needs and use the
* credentials provided at the creation of your FattureInCloud app.
*/
// Replace with your client Id
clientId: "CLIENT_ID",
// Replace with your client Secret
clientSecret: "CLIENT_SECRET",
// Replace with your redirect url
redirectUri: "http://localhost:8000/oauth",
// Replace with the required scopes
scopes: "entity.suppliers:r",
// Replace with the wanted state
state: "state",
//==============================================================================================================================================
accessTokenUri: "https://api-v2.fattureincloud.it/oauth/token",
authorizationUri: "https://api-v2.fattureincloud.it/oauth/authorize",
};
// These methods are needed for the oauth token management
export function getUri() {
var params = {
response_type: "code",
client_id: fattureInCloudOauth.clientId,
redirect_uri: fattureInCloudOauth.redirectUri,
scope: fattureInCloudOauth.scopes,
state: fattureInCloudOauth.state,
};
var query = new URLSearchParams(params).toString();
var authorizeUrl = fattureInCloudOauth.authorizationUri + "?" + query;
return authorizeUrl;
}
export async function getToken(authCode: string) {
const data = {
grant_type: "authorization_code",
client_id: fattureInCloudOauth.clientId,
client_secret: fattureInCloudOauth.clientSecret,
redirect_uri: fattureInCloudOauth.redirectUri,
code: authCode,
};
var res;
try {
res = await axios.post(fattureInCloudOauth.accessTokenUri, data);
} catch (e) {
console.error(e);
}
if (res?.status != 200) {
console.log(res?.status);
}
return res?.data;
}
💼 Find your Company ID
Even if this step is not strictly part of the Authentication process, it is required to be able to use the Company-scoped Methods. Once you obtain the Access Token, you can use the List User Companies method to retrieve the ID of the related Company; please check the Company-scoped Methods page for further info.
✅ Perform an API request
A valid Access Token can be used to authorize requests included in the scopes authorized by the user at step one; to obtain a valid response it is necessary to include the Access Token in your request as an HTTP header.
In the following example, we'll simulate a Get Supplier call. We choose this method because it is relatively easy to understand and it requires the entity.suppliers:r scope to be authorized correctly.
Please, notice that for the purposes of this example we will assume that we already know the parameters required by the request and that we have previously acquired a valid Access Token performing the steps above.
- cURL
- HTTP
curl --request GET \
--url https://api-v2.fattureincloud.it/c/17/entities/suppliers/16 \
--header 'Accept: application/json'
--header 'Authorization: Bearer a/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJZMElqc1pVWEpUZkxCSkZ3aG5iZmpSYTRJRktYTDk3ayIsImV4cCI6MTU4OTY0MjAzMX0.qn869ICUSS3_hx84ZTToMsB5slWQZjGZXGklSIiBkB4'
GET /c/17/entities/suppliers/16 HTTP/1.1
Host: api-v2.fattureincloud.it
Accept: application/json
Authorization: Bearer a/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJZMElqc1pVWEpUZkxCSkZ3aG5iZmpSYTRJRktYTDk3ayIsImV4cCI6MTU4OTY0MjAzMX0.qn869ICUSS3_hx84ZTToMsB5slWQZjGZXGklSIiBkB4
The corresponding code is the following:
- C#
- Go
- Java
- JavaScript
- PHP
- Python
- Ruby
- TypeScript
// this code uses RestSharp Client: https://restsharp.dev
// you can install it with the following command:
// dotnet add package RestSharp
using System;
using RestSharp;
namespace restclient
{
class Program
{
static void Main(string[] args)
{
// for this example we define the token as string, but you should have obtained it in the previous steps
// the token is valid for the "received_documents:r" scope needed to perform this operation
var token = "a/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJZMElqc1pVWEpUZkxCSkZ3aG5iZmpSYTRJRktYTDk3ayIsImV4cCI6MTU4OTY0MjAzMX0.qn869ICUSS3_hx84ZTToMsB5slWQZjGZXGklSIiBkB4";
// these parameters are usually retrieved through our APIs or stored in a DB
var companyId = 16;
var supplierId = 17;
var url = "https://api-v2.fattureincloud.it/c/" + companyId + "/entities/suppliers/" + supplierId,;
var client = new RestClient(url);
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer " + token);
IRestResponse response = client.Execute(request);
Console.Write(response.Content.ToString());
}
}
}
package main
import (
"io/ioutil"
"log"
"net/http"
)
func main() {
// for this example we define the token as string, but you should have obtained it in the previous steps
token := "Bearer " + "a/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJZMElqc1pVWEpUZkxCSkZ3aG5iZmpSYTRJRktYTDk3ayIsImV4cCI6MTU4OTY0MjAzMX0.qn869ICUSS3_hx84ZTToMsB5slWQZjGZXGklSIiBkB4"
// these parameters are usually retrieved through our APIs or stored in a DB
companyId := "16"
supplierId := "17"
uri := "https://api-v2.fattureincloud.it/c/" + companyId + "/entities/suppliers/" + supplierId
req, _ := http.NewRequest("GET", uri, nil)
req.Header.Add("Authorization", token)
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
log.Println("Error on response.\n[ERROR] -", err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Println("Error while reading the response bytes:", err)
}
log.Println(string([]byte(body)))
}
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import java.io.IOException;
import java.net.URL;
public class Application {
public static void main(String[] args) throws IOException {
// for this example we define the token as string, but you should have obtained it in the previous steps
String token = "a/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJZMElqc1pVWEpUZkxCSkZ3aG5iZmpSYTRJRktYTDk3ayIsImV4cCI6MTU4OTY0MjAzMX0.qn869ICUSS3_hx84ZTToMsB5slWQZjGZXGklSIiBkB4";
// these parameters are usually retrieved through our APIs or stored in a DB
Integer companyId = 16;
Integer supplierId = 17;
URL url = new HttpUrl.Builder()
.scheme("https")
.host("api-v2.fattureincloud.it")
.addPathSegments("c/" + companyId + "/entities/suppliers/" + supplierId)
.build().url();
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.header("Authorization", "Bearer " + token)
.url(url)
.build();
Response response = client.newCall(request).execute();
System.out.println(response.body().string());
}
}
var http = require("https");
// for this example we define the token as string, but you should have obtained it in the previous steps
// the token is valid for the "received_documents:r" scope needed to perform this operation
var token =
"a/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJZMElqc1pVWEpUZkxCSkZ3aG5iZmpSYTRJRktYTDk3ayIsImV4cCI6MTU4OTY0MjAzMX0.qn869ICUSS3_hx84ZTToMsB5slWQZjGZXGklSIiBkB4";
// these parameters are usually retrieved through our APIs or stored in a DB
var companyId = 16;
var supplierId = 17;
var options = {
method: "GET",
hostname: "api-v2.fattureincloud.it",
port: null,
path: "/c/" + companyId + "/entities/suppliers/" + supplierId,
headers: {
authorization: "Bearer " + token,
},
};
var req = http.request(options, function (res) {
var chunks = [];
res.on("data", function (chunk) {
chunks.push(chunk);
});
res.on("end", function () {
var body = Buffer.concat(chunks);
console.log(body.toString());
});
});
req.end();
// this code uses Guzzle HTTP Client: https://docs.guzzlephp.org/en/stable/
// and also ext-json
// you can install them with the following command:
// composer require guzzlehttp/guzzle ext-json
use GuzzleHttp\Client;
use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Psr7;
// for this example we define the token as string, but you should have obtained it in the previous steps
// the token is valid for the "entity.suppliers:r" scope needed to perform this operation
$token = 'a/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJZMElqc1pVWEpUZkxCSkZ3aG5iZmpSYTRJRktYTDk3ayIsImV4cCI6MTU4OTY0MjAzMX0.qn869ICUSS3_hx84ZTToMsB5slWQZjGZXGklSIiBkB4';
// these parameters are usually retrieved through our APIs or stored in a DB
$companyId = 17;
$supplierId = 16;
$client = new Client();
$url = "https://api-v2.fattureincloud.it/c/$companyId/entities/suppliers/$supplierId";
try {
$response = $client->request('GET', $url, [
'headers' => [
'Accept' => 'application/json',
'Authorization' => 'Bearer ' . $token,
],
]);
return json_decode((string) $response->getBody());
} catch (ClientException $e) {
echo Psr7\Message::toString($e->getRequest());
echo Psr7\Message::toString($e->getResponse());
}
import requests
# for this example we define the token as string, but you should have obtained it in the previous steps
# the token is valid for the "received_documents:r" scope needed to perform this operation
token = "a/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJYOGxDaFR4dHVsQkx0cXVVSjNCQlZEME1KOVY0NTl3QiIsImV4cCI6MTYzOTcyODAzM30.A-uMzLDpaEzGRqzUodJfdJPKo8SWMCytWUElQdOEP0c"
# these parameters are usually retrieved through our APIs or stored in a DB
company_id = 16
supplier_id = 17
url = f"https://api-v2.fattureincloud.it/c/\{company_id\}/entities/suppliers/{supplier_id}"
headers = { 'authorization': "Bearer " + token }
response = requests.get(url, headers=headers)
print(response.json())
require 'uri'
require 'net/http'
# for this example we define the token as string, but you should have obtained it in the previous steps
# the token is valid for the "received_documents:r" scope needed to perform this operation
token = "a/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJYOGxDaFR4dHVsQkx0cXVVSjNCQlZEME1KOVY0NTl3QiIsImV4cCI6MTYzOTcyODAzM30.A-uMzLDpaEzGRqzUodJfdJPKo8SWMCytWUElQdOEP0c"
# these parameters are usually retrieved through our APIs or stored in a DB
company_id = 16
supplier_id = 17
uri = URI("https://api-v2.fattureincloud.it/c/#\{company_id\}/entities/suppliers/#{supplier_id}")
headers = { authorization: "Bearer " + token}
res = Net::HTTP.get_response(uri, headers)
puts res.body
// in this example we are using the node-fetch library to make the request
import fetch, { Headers } from "node-fetch";
// for this example we define the token as a string, but you should have obtained it in the previous steps
var token =
"a/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJYOGxDaFR4dHVsQkx0cXVVSjNCQlZEME1KOVY0NTl3QiIsImV4cCI6MTYzOTcyODAzM30.A-uMzLDpaEzGRqzUodJfdJPKo8SWMCytWUElQdOEP0c";
// these parameters are usually retrieved through our APIs or stored in a DB
var companyId = 16;
var supplierId = 17;
var headers = new Headers({
"Content-Type": "application/json",
Authorization: "Bearer " + token,
});
var options = {
method: "GET",
headers: headers,
};
try {
var res = await fetch(
"https://api-v2.fattureincloud.it/c/" +
companyId +
"/entities/suppliers" +
supplierId,
options
);
var json = await res.json();
console.log(json);
} catch (err) {
console.log(err);
}
If the Access Token is valid and provided correctly in the header, the response will be a 200 OK. To check the possible error responses, please check the dedicated page.
♻️ Refreshing the token
When the Access Token expires, you have two options to keep performing authenticated requests:
- Obtain a new one performing steps 1-3
- Obtain a new one using the Refresh Token
Please, note that the first option once again requires user interaction, so we suggest performing it again only when the Refresh Token is expired.
Similar to what happens in step 3, you can obtain a new token with a POST HTTP call to the https://api-v2.fattureincloud.it/oauth/token endpoint.
The parameters required for the request are the following:
Parameter name | Description |
---|---|
grant_type | Must be set to "refresh_token". This indicates that you want to exchange a Refresh Token for an Access Token. |
client_id | Your Client ID, e.g. the identifier of your app. You can find it on your Fatture in Cloud application page (see above). |
client_secret | Your Client Secret, e.g. the secret of your app. You can find it on your Fatture in Cloud application page (see above). |
refresh_token | The Refresh Token obtained previously. |
The cURL command will look like this:
- cURL
- HTTP
curl --request POST \
--url https://api-v2.fattureincloud.it/oauth/token \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data '
{
"grant_type": "refresh_token",
"client_id": "CLIENT_ID",
"client_secret": "CLIENT_SECRET",
"refresh_token": "r/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJxaDh4bXJMM0Y0SHExWU1RSDRhcHhWTVdDR2t0SktsdiJ9.IXEqUdfQjlR6EWas1QeCzpqd8O08usvJHaMYbjwVdWY"
}
'
POST /oauth/token HTTP/1.1
Host: api-v2.fattureincloud.it
Accept: application/json
Content-Type: application/json
Content-Length: 275
{
"grant_type": "authorization_code",
"client_id": "CLIENT_ID",
"client_secret": "CLIENT_SECRET",
"refresh_token": "r/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJxaDh4bXJMM0Y0SHExWU1RSDRhcHhWTVdDR2t0SktsdiJ9.IXEqUdfQjlR6EWas1QeCzpqd8O08usvJHaMYbjwVdWY"
}
Below you can find some vanilla code examples:
- C#
- Go
- Java
- JavaScript
- PHP
- Python
- Ruby
- TypeScript
// this code uses RestSharp Client: https://restsharp.dev
// you can install it with the following command:
// dotnet add package RestSharp
using System;
using RestSharp;
namespace restclient
{
class Program
{
static void Main(string[] args)
{
// for this example we define the code as string, but you should have obtained it in the previous steps
var refreshToken = "r/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJDRENzRVlGaE5YZ0NkWDhldW1GRnVxcllIUDdYTTk2dyIsImV4cCI6MTU4OTQ2NjYzNn0.v9yyzsdC50mRF8gue46WjXqO2ADfSPZH9SZc-QTHO542";
var baseUrl = "https://api-v2.fattureincloud.it";
var tokenPath = "/oauth/token";
var clientId = "CLIENT_ID"; // your client id
var clientSecret = "CLIENT_SECRET"; // your client secret
var params = new {
grant_type = "refresh_token",
client_id = clientId,
client_secret = clientSecret,
refreshToken = refreshToken
};
var client = new RestClient(baseUrl + tokenPath);
var request = new RestRequest(Method.POST);
request.AddHeader("authorization", "Bearer " + token);
request.AddHeader("content-type", "application/json");
request.AddJsonBody(params);
IRestResponse response = client.Execute(request);
Console.Write(response.Content.ToString());
}
}
}
package main
import (
"bytes"
"encoding/json"
"io/ioutil"
"log"
"net/http"
)
func main() {
// in this example we define the code as string, but you should have obtained it in the previous steps
refreshToken := "r/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJDRENzRVlGaE5YZ0NkWDhldW1GRnVxcllIUDdYTTk2dyIsImV4cCI6MTU4OTQ2NjYzNn0.v9yyzsdC50mRF8gue46WjXqO2ADfSPZH9SZc-QTHO542"
baseUrl := "http://api-v2.local.fattureincloud.it"
tokenPath := "/oauth/token"
clientId := "CLIENT_ID" // your client id
clientSecret := "CLIENT_SECRET" // your client secret
params := map[string]string{
"grant_type": "refresh_token",
"client_id": clientId,
"client_secret": clientSecret,
"refresh_token": refreshToken,
}
reqBody, _ := json.Marshal(params)
resp, err := http.Post(baseUrl+tokenPath, "application/json", bytes.NewBuffer(reqBody))
if err != nil {
log.Println("Error on response.\n[ERROR] -", err)
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Println("Error while reading the response bytes:", err)
}
log.Println(string([]byte(body)))
}
// this code uses OkHttpClient
import okhttp3.*;
import java.io.IOException;
import java.net.URL;
public class Application {
public static void main(String[] args) throws IOException {
// for this example we define the code as string, but you should have obtained it in the previous steps
String refreshToken = "r/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJDRENzRVlGaE5YZ0NkWDhldW1GRnVxcllIUDdYTTk2dyIsImV4cCI6MTU4OTQ2NjYzNn0.v9yyzsdC50mRF8gue46WjXqO2ADfSPZH9SZc-QTHO54";
String clientId = "CLIENT_ID"; // your client id
String clientSecret = "CLIENT_SECRET"; // your client secret
host = "api-v2.fattureincloud.it";
String accessTokenUri = "/oauth/token";
RequestBody formBody = new FormBody.Builder()
.add("grant_type", "authorization_code")
.add("client_id", clientId)
.add("client_secret", clientSecret)
.add("refresh_token", refreshToken)
.build();
Request request = new Request.Builder()
.url("https://" + host + accessTokenUri)
.post(formBody)
.build();
OkHttpClient client = new OkHttpClient();
Call call = client.newCall(request);
Response response = call.execute();
System.out.println(response.body().string());
}
}
var http = require("https");
// for this example we define the code as string, but you should have obtained it in the previous steps
var refreshToken = 'r/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJDRENzRVlGaE5YZ0NkWDhldW1GRnVxcllIUDdYTTk2dyIsImV4cCI6MTU4OTQ2NjYzNn0.v9yyzsdC50mRF8gue46WjXqO2ADfSPZH9SZc-QTHO54';
var baseUrl = 'https://api-v2.fattureincloud.it';
var tokenPath = '/oauth/token';
var clientId = 'CLIENT_ID'; // your client id
var clientSecret = 'CLIENT_SECRET'; // your client secret
var params = [
'grant_type': 'refresh_token',
'client_id': clientId,
'client_secret': clientSecret,
'refresh_token': refreshToken
];
var options = {
"method": "POST",
"hostname": baseUrl,
"port": null,
"path": tokenPath,
"headers": {
"content-type": "application/json"
}
};
var req = http.request(options, function (res) {
var chunks = [];
res.on("data", function (chunk) {
chunks.push(chunk);
});
res.on("end", function () {
var body = Buffer.concat(chunks);
console.log(body.toString());
});
});
req.write(JSON.stringify(params));
req.end();
// this code uses Guzzle HTTP Client: https://docs.guzzlephp.org/en/stable/
// and also ext-json
// you can install them with the following command:
// composer require guzzlehttp/guzzle ext-json
use GuzzleHttp\Client;
use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Psr7;
// for this example we define the token as string, but you should have obtained it previously
$refreshToken = 'r/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJxaDh4bXJMM0Y0SHExWU1RSDRhcHhWTVdDR2t0SktsdiJ9.IXEqUdfQjlR6EWas1QeCzpqd8O08usvJHaMYbjwVdWY';
$client = new Client();
$baseUrl = 'https://api-v2.fattureincloud.it';
$tokenPath = '/oauth/token';
$clientId = 'CLIENT_ID'; // your client id
$clientSecret = 'CLIENT_SECRET'; // your client secret
$tokenUrl = $baseUrl . $tokenPath;
$params = [
'grant_type' => 'refresh_token',
'client_id' => $clientId,
'client_secret' => $clientSecret,
'refresh_token' => $refreshToken
];
try {
$response = $client->request('POST', $tokenUrl, [
'json' => $params
]);
return json_decode((string) $response->getBody());
} catch (ClientException $e) {
echo Psr7\Message::toString($e->getRequest());
echo Psr7\Message::toString($e->getResponse());
}
import requests
# for this example we define the code as string, but you should have obtained it in the previous steps
refresh_token = 'r/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJDRENzRVlGaE5YZ0NkWDhldW1GRnVxcllIUDdYTTk2dyIsImV4cCI6MTU4OTQ2NjYzNn0.v9yyzsdC50mRF8gue46WjXqO2ADfSPZH9SZc-QTHO54'
base_url = 'https://api-v2.fattureincloud.it'
token_path = '/oauth/token'
client_id = 'CLIENT_ID' # your client id
client_secret = 'CLIENT_SECRET' # your client secret
params = {
'grant_type': 'refresh_token',
'client_id': client_id,
'client_secret': client_secret,
'refresh_token': refresh_token
}
response = requests.post(base_url + token_path, data=params)
print(response.json())
require 'uri'
require 'net/http'
# for this example we define the code as string, but you should have obtained it in the previous steps
refresh_token = 'r/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJDRENzRVlGaE5YZ0NkWDhldW1GRnVxcllIUDdYTTk2dyIsImV4cCI6MTU4OTQ2NjYzNn0.v9yyzsdC50mRF8gue46WjXqO2ADfSPZH9SZc-QTHO54'
base_url = 'https://api-v2.fattureincloud.it'
token_path = '/oauth/token'
client_id = 'CLIENT_ID' # your client id
client_secret = 'CLIENT_SECRET' # your client secret
params = {
grant_type: 'refresh_token',
client_id: client_id,
client_secret: client_secret,
refresh_token: refresh_token
}
uri = URI(base_url + token_path)
res = Net::HTTP.post_form(uri, params)
puts res.body
// in this example we are using the node-fetch library to make the request
import fetch, { Headers } from "node-fetch";
// for this example we define the code as string, but you should have obtained it in the previous steps
var refreshToken =
"r/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJDRENzRVlGaE5YZ0NkWDhldW1GRnVxcllIUDdYTTk2dyIsImV4cCI6MTU4OTQ2NjYzNn0.v9yyzsdC50mRF8gue46WjXqO2ADfSPZH9SZc-QTHO54";
var baseUrl = "https://api-v2.fattureincloud.it";
var tokenPath = "/oauth/token";
var clientId = "CLIENT_ID"; // your client id
var clientSecret = "CLIENT_SECRET"; // your client secret
var params = {
grant_type: "refresh_token",
client_id: clientId,
client_secret: clientSecret,
refresh_token: refreshToken,
};
var headers = new Headers({
"Content-Type": "application/json",
});
var options = {
method: "POST",
body: JSON.stringify(params),
headers: headers,
};
try {
var res = await fetch(baseUrl + tokenPath, options);
var json = await res.json();
console.log(json);
} catch (err) {
console.log(err);
}
The response body will be similar to the following:
{
"token_type": "bearer",
"access_token": "a/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJZMElqc1pVWEpUZkxCSkZ3aG5iZmpSYTRJRktYTDk3ayIsImV4cCI6MTU4OTY0MjAzMX0.qn869ICUSS3_hx84ZTToMsB5slWQZjGZXGklSIiBkB4",
"refresh_token": "r/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZWYiOiJRUWVwVUgxOFJwY05oN0hoR0g4Rmsxd3BnZUFOSHBBMiJ9.dkStK6xIY-wgjwdQZZF5rrjH_tfLr4BB4dfGB7zuLO8",
"expires_in": 86400
}
The returned parameters are:
Parameter name | Description |
---|---|
token_type | Set as "bearer", it indicates how to use the returned token in the following REST calls. |
access_token | The Access Token. |
refresh_token | The Refresh Token. |
expires_in | The validity of the Access Token in seconds before its expiration. |
The obtained token can be used exactly as explained in step 3 of this guide.
📝 Change Token permissions
Unfortunately, if you need to change the set of permissions that you are currently requiring from your app users, you can't do it by preserving the old token: you must discard the old token on your code and replace it with a new one obtained after updating the scopes list at Step 1.
📚 OAuth 2.0 libraries
Here you can find a useful non-exhaustive list of OAuth 2.0 Client libraries for different programming languages. You can use them to take care of some of the tedious tasks in this guide for you, such as the composition of the redirect URL or the retrieval of the Access Token. Feel free to choose the one that best fits your needs.