Refund bank payments

When you receive a bank payment, you have the option to issue a refund. This is done using the payment initiation ID. Essentially, issuing a refund is making a payout from your merchant account. When you initiate a refund, it creates a payout that requires auhtorisation from an authoriser. To track the progress of the refund, you can refer to the 'payment attempts' section in the JSON response of the payment request. For a more detailed understanding, including step-by-step guidance, visit the NoFrixion documentation on payment attempts here.

Payment initiation ID: This is the unique ID associated with each bank payment attempt against a payment request. This is the "attemptKey" property of the payment attempt json.

To refund a bank payment, use the payouts POST action to create a payout. Include the payment initiation ID in the YourReference of the request body as "REFUND-<PAYMENT_INITIATION_ID>". Following code examples show how to create a refund payout:

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";

string paymentInittiationID = "<PAYMENT_INITIATION_ID>";

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 = $"REFUND-{paymentInittiationID}",
    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";

const paymentInittiationID = "<PAYMENT_INITIATION_ID>";

// 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: `REFUND-${paymentInittiationID}`,
    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"

payment_initiation_id = "<PAYMENT_INITIATION_ID>";

# 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": f'REFUND-{payment_initiation_id}',
    "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}

🚧

Note that the amount in this payout has to be less than or equal to the paid amount.