Sending payments

Overview

Payments are sent using the Payouts API, which involves a two-step procedure to accommodate diverse business operations:

  1. Creation of a payout record, as detailed here.
  2. Authorisation of the payout record for payment, as explained here.

These steps are designed to provide flexibility for developers, enabling everything from the creation and submission of an individual payout to the batch authorization of several payouts.

Creating a payout

Pre-requisites

You will need a few details to make API request to create a payout:

  1. Account ID: This is the source payment account ID which is associated to your merchant in MoneyMoov. You can use Get merchant accounts endpoint to get all the payment accounts associated with your merchant. Alternatively, you can use the Accounts API to get all accounts associated with you. To call this API endpoint you will need the merchant ID which you can get using the Merchants API. The account you choose as source account should be of the currency you are creating the payout for.

  2. Destination details: You can use test credentials for destination account details:

    1. For EUR payout, you can use test IBANs provided here.
    2. For GBP payout, you can use test account numbers and sort codes provided here.
    3. For BTC payout, you can create a testnet address on your wallet. Follow instructions provided here to create a test address.

    📘

    Sandbox Test Destinations

    The destinations in the table below can be used to test error conditions. All other destinations in sandbox will be processed as normal but will not move any real money. For Bitcoin in sandbox transactions will be generated and broadcast to the Bitcoin testnet.

    TypeDestinationError
    IBAN (EUR)IE06MOCK91000100000999Insufficient funds
    SCAN (GBP)SortCode: 000000, Account Number: 000999Insufficient funds
    Bitcoin (BTC)miqNJ3kKtM8EeoBFfNr1TpXUHix85J2jnYInsufficient funds
  3. Authentication token: To create a payout, you can either use merchant token with "CreatePayout" merchant token permission (refer Merchant tokens for more details) or use OAuth access token.

The following code snippets provide examples of payout creation:

using System.Net.Http.Json;

var jwtToken = "<ACCESS_TOKEN>" // Access token can be either merchant or OAuth access token.

string baseUrl = "https://api-sandbox.nofrixion.com/api/v1/payouts";

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

// Creating an anonymous object that will be serialized to JSON
var data = new
{
    AccountID = "<YOUR_SOURCE_ACCOUNT_ID>",
    // Account identifier type. Can be IBAN for EUR, SCAN for GBP and BTC for Bitcoin
    Type = "IBAN", 
    // Currency can be EUR, GBP or BTC
    Currency = "EUR",
    Amount = "19.99",
    YourReference = "My Ref",
    Destination = new
    {
        Name = "Dest Name",
        Identifier = new
        {
            // For EUR payment you can use IBAN
            IBAN = "GB94BARC10201530093459",
            //BIC = "BARCGB22",
            
            // For GBP payment you can use SortCode and AccountNumber
            // SortCode = "102015",
            // AccountNumber = "30093459",
            
            // For Bitcoin payment you can use BitcoinAddress
            // BitcoinAddress = "1BvBMSEYstWetqTFn5Au4m4GFg7xJaNVN2"
        }
    },
    TheirReference = "Their Ref",
    // Parameters to schedule this payout to process on a later date
    // Scheduled = true,
    // ScheduleDate = DateTimeOffset.Now + TimeSpan.FromHours(1)
};

HttpResponseMessage response = await client.PostAsJsonAsync(baseUrl, data);
if (response.IsSuccessStatusCode)
{
    // "Created" on success
    Console.WriteLine(response.StatusCode);

    // The newly created 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');

// Access token can be either merchant or OAuth access token.
const jwtToken = "<ACCESS_TOKEN>";

const baseUrl = "https://api-sandbox.nofrixion.com/api/v1/payouts";

// Creating an object that will be serialized to JSON
const data = {
    AccountID: "<YOUR_SOURCE_ACCOUNT_ID>",
    // Account identifier type. Can be IBAN for EUR, SCAN for GBP, and BTC for Bitcoin
    Type: "IBAN", 
    // Currency can be EUR, GBP, or BTC
    Currency: "EUR",
    Amount: "19.99",
    YourReference: "My Ref",
    Destination: {
        Name: "Dest Name",
        Identifier: {
            // For EUR payment you can use IBAN
            IBAN: "GB94BARC10201530093459",
            // BIC: "BARCGB22",

            // For GBP payment you can use SortCode and AccountNumber
            // SortCode: "102015",
            // AccountNumber: "30093459",

            // For Bitcoin payment you can use BitcoinAddress
            // BitcoinAddress: "1BvBMSEYstWetqTFn5Au4m4GFg7xJaNVN2"
        }
    },
    TheirReference: "Their Ref",
    // Parameters to schedule this payout to process on a later date
    // Scheduled: true,
    // ScheduleDate: new Date(Date.now() + 3600000).toISOString() // Adds 1 hour to current time
};

// Function to perform the POST request
async function postPayout() {
    try {
        const response = await axios.post(baseUrl, data, {
            headers: {
                'Accept': 'application/json',
                'Authorization': `Bearer ${jwtToken}`
            }
        });

        if (response.status === 201) {
            // "Created" on success
            console.log('Status Code:', response.status);

            // The newly created payout object will be returned in the response body
            console.log(response.data);
        } else {
            // HTTP error codes will return a MoneyMoov API problem object
            console.log('Error:', response.status, response.data);
        }
    } catch (error) {
        console.error('Error:', error.response ? error.response.data : error.message);
    }
}

// Call the function to perform the POST request
postPayout();

// Type definitions for returned data (used for reference, not needed in actual Node.js code)
// AccountIdentifier: { type, currency, iban, bic, sortCode, accountNumber, bitcoinAddress }
// Counterparty: { name, Identifier }
// Payout: { id, accountID, merchantID, currentUserID, currentUserRole, approvePayoutUrl, userID, type, description, currency, amount, yourReference, destination, theirReference }
// ApiProblem: { type, title, status, detail }

import requests
import json
from datetime import datetime, timedelta

# Access token can be either merchant or OAuth access token.
jwt_token = "<ACCESS_TOKEN>"

base_url = "https://api-sandbox.nofrixion.com/api/v1/payouts"

# Set up headers for the HTTP request
headers = {
    "Accept": "application/json",
    "Authorization": f"Bearer {jwt_token}"
}

# Creating a data object that will be serialized to JSON
data = {
    "AccountID": "<YOUR_SOURCE_ACCOUNT_ID>",
    # Account identifier type. Can be IBAN for EUR, SCAN for GBP, and BTC for Bitcoin
    "Type": "IBAN", 
    # Currency can be EUR, GBP, or BTC
    "Currency": "EUR",
    "Amount": "19.99",
    "YourReference": "My Ref",
    "Destination": {
        "Name": "Dest Name",
        "Identifier": {
            # For EUR payment you can use IBAN
            "IBAN": "GB94BARC10201530093459",
            # "BIC": "BARCGB22",
            
            # For GBP payment you can use SortCode and AccountNumber
            # "SortCode": "102015",
            # "AccountNumber": "30093459",
            
            # For Bitcoin payment you can use BitcoinAddress
            # "BitcoinAddress": "1BvBMSEYstWetqTFn5Au4m4GFg7xJaNVN2"
        }
    },
    "TheirReference": "Their Ref",
    # Parameters to schedule this payout to process on a later date
    # "Scheduled": True,
    # "ScheduleDate": (datetime.now() + timedelta(hours=1)).isoformat()
}

# Make the POST request
response = requests.post(base_url, headers=headers, json=data)

if response.status_code == 201:
    # "Created" on success
    print(f"Status Code: {response.status_code}")

    # The newly created payout object will be returned in the response body
    print(response.json())
else:
    # HTTP error codes will return a MoneyMoov API problem object
    print(f"Error: {response.status_code}")
    print(response.json())

# Type definitions for returned data (used for reference, not needed in actual Python code)
# AccountIdentifier: {type, currency, iban, bic, sortCode, accountNumber, bitcoinAddress}
# Counterparty: {name, Identifier}
# Payout: {id, accountID, merchantID, currentUserID, currentUserRole, approvePayoutUrl, userID, type, description, currency, amount, yourReference, destination, theirReference}
# ApiProblem: {type, title, status, detail}

Remember, the payment is not processed when the payout is created, it still needs to be authorised to complete the process. Refer Authorising a payout for more details.