Authorising a payout

📘

Strong customer authentication

Strong Customer Authentication (SCA) is a critical security protocol designed to protect financial transactions from fraud and unauthorised access. In the context of NoFrixion's MoneyMoov API, SCA is implemented to ensure the highest level of security during the payout process. This section explains how SCA works in our system and the steps involved in the authentication process.

What is Strong Customer Authentication?
SCA is a requirement of the PSD2 regulation in the European Union. It mandates a two-factor authentication process for online payments and financial transactions. This means that to complete a transaction, a user must provide at least two of the following three forms of identification:

Knowledge: Something only the user knows (e.g., a password or PIN).
Possession: Something only the user possesses (e.g., a mobile phone or security token).
Inherence: Something inherent to the user (e.g., a fingerprint or facial recognition).

Pre-requisites

1. Set up MFA on NoFrixion Identity Server

Before an authoriser can authorise payouts, they must set up MFA on the NoFrixion Identity Server. Here's how this is done:

  1. Navigate to NoFrixion Identity server's Manage your account page.
  2. Setup a security key or one time password under Two-factor authentication section.

Generating strong access token

In MoneyMoov, a payout is a transaction that moves money from your account and requires secure authorisation through strong customer authentication. This process is crucial for ensuring the safety of your financial transactions. To authorise a payout and secure a strong access token, a specific procedure needs to be followed. Detailed instructions for this can be found in their documentation here.

Submitting a payout

A payout can be submitted for processing through the payouts/submit/{id} POST endpoint, as demonstrated below. Use the strong access token mentioned above.

using System.Net.Http.Json;

var payoutIDToSubmit = "<PAYOUT_ID_TO_SUBMIT>";

var jwtToken = "<STRONG_ACCESS_TOKEN>"; // Replace with your strong access token

string payoutSubmitUrl = $"https://api-sandbox.nofrixion.com/api/v1/payouts/submit/{payoutIDToSubmit}";

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

HttpResponseMessage response = await client.PostAsync(payoutSubmitUrl, null);
if (response.IsSuccessStatusCode)
{
    // "Accepted" on success
    Console.WriteLine(response.StatusCode);

    // The submitted payout object will be returned in the response body
    Console.WriteLine(await response.Content.ReadFromJsonAsync<Payout>());
}
else
{
    // HTTP error codes will return a MoneyMoov API problem object
    Console.WriteLine(await response.Content.ReadFromJsonAsync<ApiProblem>());
}

// Type definitions for returned data
record AccountIdentifier(string type, string currency, string iban, string bic, string sortCode, string accountNumber, string bitcoinAddress);

record Counterparty(string name, AccountIdentifier Identifier);
record Payout(string id, string accountID, string merchantID, string currentUserID, string currentUserRole, 
    string approvePayoutUrl, string userID, string type, string description, string currency,
    decimal amount, string yourReference, Counterparty destination, string theirReference);

record ApiProblem(string type, string title, int status, string detail);
const axios = require('axios');

async function submitPayout() {
    const payoutIDToSubmit = "<PAYOUT_ID_TO_SUBMIT>"; // Replace with the payout ID you want to submit
    const jwtToken = "<STRONG_ACCESS_TOKEN>"; // Replace with your strong access token

    const payoutSubmitUrl = `https://api-sandbox.nofrixion.com/api/v1/payouts/submit/${payoutIDToSubmit}`;

    try {
        const response = await axios.post(payoutSubmitUrl, null, {
            headers: {
                'Accept': 'application/json',
                'Authorization': `Bearer ${jwtToken}`
            }
        });

        if (response.status === 202) {
            // "Accepted" on success
            console.log(response.status);

            // The submitted payout object will be returned in the response body
            console.log(response.data);
        }
    } catch (error) {
        if (error.response) {
            // HTTP error codes will return a MoneyMoov API problem object
            console.log(error.response.data);
        } else {
            console.log(error.message);
        }
    }
}

submitPayout();

import requests
import json

# Replace with the ID of the payout you want to submit
payout_id_to_submit = "<PAYOUT_ID_TO_SUBMIT>"

# Replace with your strong access token
jwt_token = "<STRONG_ACCESS_TOKEN>"

# Construct the URL for submitting the payout
payout_submit_url = f"https://api-sandbox.nofrixion.com/api/v1/payouts/submit/{payout_id_to_submit}"

# Set up the headers with the JWT token for authorization
headers = {
    "Accept": "application/json",
    "Authorization": f"Bearer {jwt_token}"
}

# Make the POST request
response = requests.post(payout_submit_url, headers=headers)

# Check if the request was successful
if response.status_code == requests.codes.ok:
    # "Accepted" on success
    print(response.status_code)

    # The submitted payout object will be returned in the response body
    print(response.json())
else:
    # HTTP error codes will return a MoneyMoov API problem object
    print(response.json())