User access tokens

Most MoneyMoov API tasks require a user access token for authentication (the exception here is dealing with payment requests, which use merchant tokens).

Creating user tokens

User access token creation can be initiated using the NoFrixion Portal or via the MoneyMoov API.

The following examples show how to initiate user token creation using the MoneyMoov API. These examples return a pre-token containing an "approveTokenUrl" property. In order to complete the token creation process redirect the user to the approval URL, where they will be:

  • asked to complete strong authentication.
  • redirected to the NoFrixion portal where they will be able to view their access token and the refresh token.

Note, user access tokens are not stored in the NoFrixion database, so user's must keep a secure copy of these.

using System.Net.Http.Json;

const string baseUrl = "<<SANDBOX_URL>>user/tokens";

var jwtToken = Environment.GetEnvironmentVariable("NOFRIXION_USER_TOKEN");

var client = new HttpClient();

client.DefaultRequestHeaders.Add("Accept", "application/json");
client.DefaultRequestHeaders.Add("Authorization", $"Bearer {jwtToken}");

var data = new Dictionary<string, string>();
data.Add("MerchantID","xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx");
data.Add("Description","API created user token");

HttpContent postData = new FormUrlEncodedContent(data);

try
{
    var response = await client.PostAsync(baseUrl, postData);
    if (response.IsSuccessStatusCode)
    {
        var preToken = await response.Content.ReadFromJsonAsync<UserToken>();
        if (preToken != null)
        {
            // The response body contains a JSON 'pre-token'. Redirect the user to the approveTokenUrl
            // where they will be asked to perform strong authentication and then redirected back
            // to the NoFrixion portal where their token and refresh token will be visible.
            Console.WriteLine(preToken.approveTokenUrl);
        }
        else
        {
            Console.WriteLine("No user token created.");
        }
    }
    else
    {
        // HTTP error codes will return a MoneyMoov API problem object
        Console.WriteLine(await response.Content.ReadFromJsonAsync<ApiProblem>());
    }
}
catch (Exception e)
{
    Console.WriteLine($"Error: {e.Message}");
}

// Type definitions for response data
record UserToken(string id, string userID, string type, string description, string accessTokenHash,
            string refreshTokenHash, string inserted, string lastUpdated, string approveTokenUrl);

record ApiProblem(string type, string title, int status, string detail);
// These modules allow the code to run on Node.js, they aren't required if running in a browser.
const fetch = require('cross-fetch');
const FormData = require('form-data');

// Remember, the JWT access token must be securely store - this example uses an environment variable
const jwtToken = process.env.NOFRIXION_USER_TOKEN;

const baseUrl = '<<SANDBOX_URL>>user/tokens';

// Example form data
const formData = new FormData();
formData.append('MerchantID', 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx');
formData.append('Description', 'API Created Token');

const options = {
    method: 'POST',
    headers: {
        Accept: 'application/json',
        Authorization: 'Bearer ' + jwtToken
    },
    body: formData
};

fetch(baseUrl, options)
    .then(response => response.json())
    // The response body contains a JSON 'pre-token'. Redirect the user to the approveTokenUrl
    // where they will be asked to perform strong authentication and then redirected back
    // to the NoFrixion portal where their token and refresh token will be visible.
    .then(response => console.log(response))
    .catch(err => console.error(err));
# The 'requests' library for Python can be used to make calls to the MoneyMoov API in
# popular python frameworks such as Django and Flask.
import requests
import os

# Remember, the JWT access token must be securely stored ('os' module above allows storage in environment variable)
jwtToken = os.environ['NOFRIXION_USER_TOKEN']

baseUrl = "<<SANDBOX_URL>>user/tokens"

headers = {
    "Accept": "application/json",
    "Authorization": f"Bearer {jwtToken}"
}

tokenData = {
    "MerchantID": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "Description": "API Created Token"
}

response = requests.request("POST", baseUrl, headers=headers, data=tokenData)

if response.ok:
    # After pre-token creation, redirect the user to the approveTokenUrl
    # where they will be asked to perform strong authentication and then redirected back
    # to the NoFrixion portal where their token and refresh token will be visible.
    preToken = response.json()
    print(preToken["approveTokenUrl"])
else:
    # If not OK, response contains MoneyMoov problem (https://docs.nofrixion.com/reference/error-messages)
    print(response.json())

Refreshing user tokens

It is not necessary to have the user authenticate every time an access token expires. Refresh tokens are part of the OAUTH 2.0 standard, and can be used with the MoneyMoov API. The following examples show how to use refresh tokens with MoneyMoov via the the user/tokens/refresh POST action:

using System.Net.Http.Json;

const string baseUrl = "<<SANDBOX_URL>>user/tokens/refresh";

var jwtToken = Environment.GetEnvironmentVariable("NOFRIXION_USER_TOKEN");

var client = new HttpClient();

client.DefaultRequestHeaders.Add("Accept", "application/json");
client.DefaultRequestHeaders.Add("Authorization", $"Bearer {jwtToken}");

var data = new Dictionary<string, string>();
data.Add("refreshToken", "v1.M-mv0QKNnusz..........");

HttpContent postData = new FormUrlEncodedContent(data);
try
{
    var response = await client.PostAsync(baseUrl, postData);
    if (response.IsSuccessStatusCode)
    {
        var newToken = await response.Content.ReadFromJsonAsync<UpdatedToken>();
        if (newToken != null)
        {
            // The response body contains a new user access and refresh tokens. 
            // These must be securely stored - they ARE NOT stored in the NoFrixion database.
            Console.WriteLine(newToken.accessToken);
            Console.WriteLine(newToken.refreshToken);
        }
        else
        {
            Console.WriteLine("No token returned.");
        }
    }
    else
    {
        // HTTP error codes will return a MoneyMoov API problem object
        Console.WriteLine(await response.Content.ReadFromJsonAsync<ApiProblem>());
    }
}
catch (Exception e)
{
    Console.WriteLine($"Error: {e.Message}");
}

// Type definitions for response data
record ApiProblem(string type, string title, int status, string detail);
record UpdatedToken(string accessToken, string refreshToken);
// These modules allow the code to run on Node.js, they aren't required if running in a browser.
const fetch = require('cross-fetch');
const FormData = require('form-data');

// Remember, the JWT access token must be securely store - this example uses an environment variable
const jwtToken = process.env.NOFRIXION_USER_TOKEN;

const url = '<<SANDBOX_URL>>/user/tokens/refresh';

// Example form data
const formData = new FormData();
formData.append("refreshToken", "v1.Mumv0QKNnusz....");

const options = {
    method: 'POST',
    headers: {
        Accept: 'application/json', 
        Authorization: 'Bearer ' + jwtToken
    },
    body: formData
};

fetch(url, options)
    .then(response => response.json())
    // the json response contains the new user token (accessToken) and a new refresh token (refreshToken)
    .then(response => console.log(response))
    .catch(err => console.error(err));
# The 'requests' library for Python can be used to make calls to the MoneyMoov API in
# popular python frameworks such as Django and Flask.
import requests
import os

# Remember, the JWT access token must be securely stored ('os' module above allows storage in environment variable)
jwtToken = os.environ['NOFRIXION_USER_TOKEN']

baseUrl = "<<SANDBOX_URL>>user/tokens/refresh"

headers = {
    "Accept": "application/json",
    "Authorization": f"Bearer {jwtToken}"
}

refreshToken = {
    "refreshToken": "v1.Me3Ofa9G9pZxLgqhJOaO3rnPv7iRjGY9gH7XysJ.........."
}

response = requests.request("POST", baseUrl, headers=headers, data=refreshToken)

if response.ok:
    # The json response contains the new user token (accessToken) and a new refresh token (refreshToken)
    # Save these, the are not stored in the database.
    newTokens = response.json()
    print(newTokens["accessToken"])
    print(newTokens["refreshToken"])
else:
    # If not OK, response contains MoneyMoov problem (https://docs.nofrixion.com/reference/error-messages)
    print(response.json())

For more information on

Viewing user tokens

A list of tokens issued to the current user can be retrieved using the user/tokens GET action. For example:

using System.Net.Http.Json;

const string baseUrl = "<<SANDBOX_URL>>user/tokens";

// Note optional url paramaters for paging the token list are exposed in the API
// - see https://api-sandbox.nofrixion.com/swagger/index.html for full details

var jwtToken = Environment.GetEnvironmentVariable("NOFRIXION_USER_TOKEN");

var client = new HttpClient();

client.DefaultRequestHeaders.Add("Accept", "application/json");
client.DefaultRequestHeaders.Add("Authorization", $"Bearer {jwtToken}");

try
{
    var response = await client.GetAsync(baseUrl);
    if (response.IsSuccessStatusCode)
    {
        var userTokens = await response.Content.ReadFromJsonAsync<UserTokensPage>();
        if (userTokens != null && userTokens.content != null)
        {
            foreach (var token in userTokens.content)
            {
                // Display token information
                Console.WriteLine(token);
            }
        }
        else
        {
            Console.WriteLine("No user tokens found.");
        }
    }
    else
    {
        // HTTP error codes will return a MoneyMoov API problem object
        Console.WriteLine(await response.Content.ReadFromJsonAsync<ApiProblem>());
    }
}
catch (Exception e)
{
    Console.WriteLine($"Error: {e.Message}");
}


// Type definitions for returned data
record UserToken(string id, string userID, string type, string description, string accessTokenHash,
            string refreshTokenHash, string inserted, string lastUpdated, string approveTokenUrl);

record UserTokensPage(List<UserToken> content, int pageNumber, int pageSize, int totalPages, int totalSize);
record ApiProblem(string type, string title, int status, string detail);
// This package allows the script to run on node.js, not required for browser use.
const fetch = require('cross-fetch');

// Remember, the JWT access token must be securely store - this example uses an environment variable
const jwtToken = process.env.NOFRIXION_USER_TOKEN;

const baseUrl = '<<SANDBOX_URL>>user/tokens';

// Note optional url paramaters for paging the token list are exposed in the API
// - see https://api-sandbox.nofrixion.com/swagger/index.html for full details

const options = { method: 'GET', headers: { Accept: 'application/json', Authorization: 'Bearer ' + jwtToken } };

fetch(baseUrl, options)
    .then(response => response.json())
    .then(responseJson => {
        // Returns JSON object containing a page of the authenticated user's access tokens.
        console.log(responseJson);
    })
    .catch(err => console.error(err));
# The 'requests' module for Python can be used to make calls to the MoneyMoov API in popular python frameworks such as Django and Flask.
import requests
import os

# Remember, the JWT access token must be securely stored ('os' module above allows storage in environment variable)
jwtToken = os.environ['NOFRIXION_USER_TOKEN']

baseUrl = "<<SANDBOX_URL>>user/tokens"

# Note optional url paramaters for paging the token list are exposed in the API
# - see https://api-sandbox.nofrixion.com/swagger/index.html for full details

headers = {
    "Accept": "application/json",
    "Authorization": f"Bearer {jwtToken}"
}

try:
    response = requests.request("GET", baseUrl, headers=headers)

    if response.ok:
        # Returns JSON object containing page metadata and tokens.
        tokensPage = response.json()
        #  User tokens are stored in 'content' property, do something with these...
        print(tokensPage["content"])
    else:
        # If not OK, response contains MoneyMoov problem (https://docs.nofrixion.com/reference/error-messages)
        print(response.json())
        
except Exception as ex:
    print(ex)

An individual user token can also be retrieved by specifying the relevant token ID in the user/tokens/{tokenID} GET action. For example:

using System.Net.Http.Json;

const string baseUrl = "<<SANDBOX_URL>>user/tokens";

var jwtToken = Environment.GetEnvironmentVariable("NOFRIXION_USER_TOKEN");

string tokenID = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";

var client = new HttpClient();

client.DefaultRequestHeaders.Add("Accept", "application/json");
client.DefaultRequestHeaders.Add("Authorization", $"Bearer {jwtToken}");

try
{
    var response = await client.GetAsync($"{baseUrl}/{tokenID}");
    if (response.IsSuccessStatusCode)
    {
        // Display token information
        var userToken = await response.Content.ReadFromJsonAsync<UserToken>();
        Console.WriteLine(userToken);
    }
    else
    {
        // HTTP error codes will return a MoneyMoov API problem object
        Console.WriteLine(await response.Content.ReadFromJsonAsync<ApiProblem>());
    }
}
catch (Exception e)
{
    Console.WriteLine($"Error: {e.Message}");
}


// Type definitions for returned data
record UserToken(string id, string userID, string type, string description, string accessTokenHash,
            string refreshTokenHash, string inserted, string lastUpdated, string approveTokenUrl);

record ApiProblem(string type, string title, int status, string detail);
// This package allows the script to run on node.js, not required for browser use.
const fetch = require('cross-fetch');

// Remember, the JWT access token must be securely store - this example uses an environment variable
const jwtToken = process.env.NOFRIXION_USER_TOKEN;

const baseUrl = '<<SANDBOX_URL>>user/tokens';

const options = { method: 'GET', headers: { Accept: 'application/json', Authorization: 'Bearer ' + jwtToken } };

var tokenID = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx';

fetch(`${baseUrl}/${tokenID}`, options)
    .then(response => response.json())
    .then(responseJson => {
        // Returns JSON object containing specified user access token.
        console.log(responseJson);
    })
    .catch(err => console.error(err));
# The 'requests' module for Python can be used to make calls to the MoneyMoov API in popular python frameworks such as Django and Flask.
import requests
import os

# Remember, the JWT access token must be securely stored ('os' module above allows storage in environment variable)
jwtToken = os.environ['NOFRIXION_USER_TOKEN']

baseUrl = "<<SANDBOX_URL>>user/tokens"
tokenID = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

headers = {
    "Accept": "application/json",
    "Authorization": f"Bearer {jwtToken}"
}

response = requests.request("GET", f"{baseUrl}/{tokenID}", headers=headers)

if response.ok:
    # Returns JSON array containing tokens, do something with these...
    token = response.json()
    print(token)
else:
    # If not OK, response contains MoneyMoov problem (https://docs.nofrixion.com/reference/error-messages)
    print(response.json())

Deleting user tokens

If you need to invalidate an user access token it can be deleted by specifying the access token ID as shown below:

using System.Net.Http.Json;

const string baseUrl = "<<SANDBOX_URL>>user/tokens";

var jwtToken = Environment.GetEnvironmentVariable("NOFRIXION_USER_TOKEN");

string tokenID = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";

var client = new HttpClient();

client.DefaultRequestHeaders.Add("Accept", "application/json");
client.DefaultRequestHeaders.Add("Authorization", $"Bearer {jwtToken}");

try
{
    var response = await client.DeleteAsync($"{baseUrl}/{tokenID}");
    if (response.IsSuccessStatusCode)
    {
        // Status Code "OK" on successful delete (check using user/tokens GET action)
        Console.WriteLine(response.StatusCode);
    }
    else
    {
        // HTTP error codes will return a MoneyMoov API problem object
        Console.WriteLine(await response.Content.ReadFromJsonAsync<ApiProblem>());
    }
}
catch (Exception e)
{
    Console.WriteLine($"Error: {e.Message}");
}

// type definition for returned data
record ApiProblem(string type, string title, int status, string detail);
// This package allows the script to run on node.js, not required for browser use.
const fetch = require('cross-fetch');

// Remember, the JWT access token must be securely store - this example uses an environment variable
const jwtToken = process.env.NOFRIXION_USER_TOKEN;

const baseUrl = '<<SANDBOX_URL>>user/tokens';

const options = { method: 'DELETE', headers: { Accept: 'application/json', Authorization: 'Bearer ' + jwtToken } };

var tokenID = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx';

fetch(`${baseUrl}/${tokenID}`, options)
    .then(response => response.status)
    .then(responseStatus => {
        //  Status Code "200" on successful delete (check using user/tokens GET action)
        console.log(responseStatus);
    })
    .catch(err => console.error(err));
# The 'requests' module for Python can be used to make calls to the MoneyMoov API in popular python frameworks such as Django and Flask.
import requests
import os

# Remember, the JWT access token must be securely stored ('os' module above allows storage in environment variable)
jwtToken = os.environ['NOFRIXION_USER_TOKEN']

baseUrl = "<<SANDBOX_URL>>user/tokens"
tokenID = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

headers = {
    "Accept": "application/json",
    "Authorization": f"Bearer {jwtToken}"
}

response = requests.request("DELETE", f"{baseUrl}/{tokenID}", headers=headers)

if response.ok:
    # Returns HTTP status 200 on successful delete.
    print(response.status_code)
else:
    # If not OK, response contains MoneyMoov problem (https://docs.nofrixion.com/reference/error-messages)
    print(response.json())

Updating a token description

The description of a user access token can be updated using the user/tokens/{id} PUT action:

using System.Net.Http.Json;

const string baseUrl = "<<SANDBOX_URL>>user/tokens";

var jwtToken = Environment.GetEnvironmentVariable("NOFRIXION_USER_TOKEN");

string tokenID = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";

var client = new HttpClient();

client.DefaultRequestHeaders.Add("Accept", "application/json");
client.DefaultRequestHeaders.Add("Authorization", $"Bearer {jwtToken}");

// Currently only the token description can be updated.
var uptdatedToken = new Dictionary<string, string>();
uptdatedToken.Add("Description", $"Updated on {DateTime.UtcNow.ToString()}");

HttpContent putData = new FormUrlEncodedContent(uptdatedToken);

try
{
    var response = await client.PutAsync($"{baseUrl}/{tokenID}", putData);
    if (response.IsSuccessStatusCode)
    {
        // Display updated token information
        var userToken = await response.Content.ReadFromJsonAsync<UserToken>();
        Console.WriteLine(userToken);
    }
    else
    {
        // HTTP error codes will return a MoneyMoov API problem object
        Console.WriteLine(await response.Content.ReadFromJsonAsync<ApiProblem>());
    }
}
catch (Exception e)
{
    Console.WriteLine($"Error: {e.Message}");
}

// Type definitions for returned data
record UserToken(string id, string userID, string type, string description, string accessTokenHash,
            string refreshTokenHash, string inserted, string lastUpdated, string approveTokenUrl);

record ApiProblem(string type, string title, int status, string detail);
// These packages allows the script to run on node.js, not required for browser use.
const fetch = require('cross-fetch');
const FormData = require('form-data');

// Remember, the JWT access token must be securely store - this example uses an environment variable
const jwtToken = process.env.NOFRIXION_USER_TOKEN;

const baseUrl = '<<SANDBOX_URL>>user/tokens';

var tokenID = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx';

var formData = new FormData();
formData.append('Description', 'Updated description');

var options = {
    method: 'PUT',
    headers: {
        Accept: 'application/json',
        Authorization: 'Bearer ' + jwtToken
    },
    body: formData
};


fetch(`${baseUrl}/${tokenID}`, options)
    .then(response => response.json())
    .then(responseJson => {
        // Returns JSON object containing specified user access token.
        console.log(responseJson);
    })
    .catch(err => console.error(err));
# The 'requests' library for Python can be used to make calls to the MoneyMoov API in
# popular python frameworks such as Django and Flask.
import requests
import os

# Remember, the JWT access token must be securely stored ('os' module above allows storage in environment variable)
jwtToken = os.environ['NOFRIXION_USER_TOKEN']

baseUrl = "<<SANDBOX_URL>>user/tokens"

tokenID = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

headers = {
    "Accept": "application/json",
    "Authorization": f"Bearer {jwtToken}"
}

tokenData = {
    "Description": "Updated description"
}

try:
    response = requests.request("PUT", f"{baseUrl}/{tokenID}", headers=headers, data=tokenData)
    if response.ok:
        print(response.json())
    else:
        # If not OK, response contains MoneyMoov problem (https://docs.nofrixion.com/reference/error-messages)
        print(response.json())
        
except Exception as ex:
    print(ex)