Managing card payments

Once a card payment has been received, there are certain possible actions you can take:

Capture the Authorised Payment: This means finalising the transaction after it has been authorised. It's the process of confirming the payment and transferring the funds from the cardholder's account to your account.

Void the Authorised Payment: If the payment is still in the authorised stage and not yet captured, it can be cancelled. This is known as voiding the payment, and it prevents any transfer of funds from the cardholder's account.

Refund a Captured Payment: After a payment has been captured (i.e., the transaction is complete and the funds have been transferred), you can still return the funds to the cardholder. This action is called issuing a refund.

Capturing a previously authorised payment

If the CardAuthorizeOnly field was set to true when a payment request was created, the payment must still be captured in order for funds to be received. The following examples show how to capture payment for a previously authorised card payment. You can also capture a partial amount.

You will need the authorisation ID of the card payment attempt to capture it. You can get this from the payment attempts object returned as part of the payment request object. To know more about the payment attempts refer the documentation here. This is the AttemptKey property of the card payment attempt.

using System.Net.Http.Json;

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

// Payment requests use MERCHANT tokens (remember to keep these safe and secure).
var jwtToken = <MERCHANT_TOKEN>;

var client = new HttpClient();

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


// Specify the payment request ID (URL param)
string paymentRequestID = "<PAYMENT_REQUEST_ID_TO_CAPTURE>";

// Specify the authorisationID and amount to be captured from the card in the request body.
var postData = new Dictionary<string, string>();
postData.Add("AuthorizationID", "XXXXXXXXXXXXXXXXXXXXXX");
postData.Add("Amount", "1.10");

try
{
    HttpResponseMessage response = await client.PostAsync($"{baseUrl}/{paymentRequestID}/card/capture", new FormUrlEncodedContent(postData));
    if (response.IsSuccessStatusCode)
    {
        // The card payment response model will be returned in JSON object.
        Console.WriteLine(await response.Content.ReadFromJsonAsync<CardResponse>());
    }
    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 CardResponse(string authorizedAmount, string currencyCode, string responseCode, string status,
                string requestID, string transactionID, CardError error, string payerAuthenticationUrl,
                string payerAuthenticationAccessToken, int payerAuthenticationWindowWidth,
                int payerAuthenticationWindowHeight );

record CardError(int errorCode, string id, string message, string reason, string status, string[] details, string rawResponse);
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_MERCHANT_TOKEN;

const baseUrl = 'https://api-sandbox.nofrixion.com/api/v1/paymentrequests';

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

// Request body must contain amount to be captured and authorizationID
var form = new FormData();
form.append('AuthorizationID', 'XXXXXXXXXXXXXXXXXXXXXX');
form.append('Amount', '0.10');

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

fetch(`${baseUrl}/${paymentRequestID}/card/capture`, options)
    .then(response => response.json())
    // Card payment response model will be returned in JSON response object.
    .then(responseJson => 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)
# ... and when dealing with payment requests, use a MERCHANT token!
jwtToken = os.environ['NOFRIXION_MERCHANT_TOKEN']

baseUrl = "https://api-sandbox.nofrixion.com/api/v1/paymentrequests"

paymentRequestID = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

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

postData = {
    "AuthorizationID": "XXXXXXXXXXXXXXXXXXXXXX",
    "Amount": "0.10"
}

try:
    response = requests.request("POST", f"{baseUrl}/{paymentRequestID}/card/capture", headers=headers, data=postData)

    if response.ok:
        #   On success, the API returns the card payment response model 
        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)

Voiding a previously authorised payment

To void a recently authorised card transaction, use the paymentrequests/{id}/card/void action along with the authorization ID of the transaction you wish to void. Note that voiding would mean that you will not be able to capture funds after this.

using System.Net.Http.Json;
using System.Text;

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

// Payment requests use MERCHANT tokens (remember to keep these safe and secure).
var jwtToken = Environment.GetEnvironmentVariable("NOFRIXION_MERCHANT_TOKEN");

var client = new HttpClient();

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


// Specify the payment request ID
string paymentRequestID = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";

// neet to include authorizationID of transaction to void in request body
string authorizationID = "XXXXXXXXXXXXXXXXXXXXXX";

var postData = new StringContent($"authorizationID={authorizationID}", Encoding.UTF8, "application/x-www-form-urlencoded");

try
{
    HttpResponseMessage response = await client.PostAsync($"{baseUrl}/{paymentRequestID}/card/void", postData);
    if (response.IsSuccessStatusCode)
    {
        // The card payment response model will be returned in JSON object.
        Console.WriteLine(await response.Content.ReadFromJsonAsync<CardResponse>());
    }
    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 CardResponse(string authorizedAmount, string currencyCode, string responseCode, string status,
                string requestID, string transactionID, CardError error, string payerAuthenticationUrl,
                string payerAuthenticationAccessToken, int payerAuthenticationWindowWidth,
                int payerAuthenticationWindowHeight );

record CardError(int errorCode, string id, string message, string reason, string status, string[] details, string rawResponse);
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_MERCHANT_TOKEN;

const baseUrl = 'https://api-sandbox.nofrixion.com/api/v1/paymentrequests';

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

// need to specify authorizationID of transaction to be voided
var form = new FormData();
form.append('authorizationID', 'XXXXXXXXXXXXXXXXXXXXXX');

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

fetch(`${baseUrl}/${paymentRequestID}/card/void`, options)
    .then(response => response.json())
    // Card payment response model will be returned in JSON response object.
    .then(responseJson => 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)
# ... and when dealing with payment requests, use a MERCHANT token!
jwtToken = os.environ['NOFRIXION_MERCHANT_TOKEN']

baseUrl = "https://api-sandbox.nofrixion.com/api/v1/paymentrequests"
paymentRequestID = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

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

# need to specify authorizationID of transaction to be voided
postData = {
    "authorizationID": "XXXXXXXXXXXXXXXXXXXXXX"
}

try:
    response = requests.request("POST", f"{baseUrl}/{paymentRequestID}/card/void", headers=headers, data=postData)

    if response.ok:
        #  On successful void, the API returns the card payment response model with 'status': 'VOIDED'
        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)

You can also verify that a card payment was successfully voided by viewing the payments attempts of the payment request .

Refunding a captured payment

To refund a recently captured card transaction, use the paymentrequests/{id}/card/refund action along with the authorization ID of the transaction you wish to refund.

using System.Net.Http.Json;
using System.Text;

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

// Payment requests use MERCHANT tokens (remember to keep these safe and secure).
var jwtToken = Environment.GetEnvironmentVariable("NOFRIXION_MERCHANT_TOKEN");

var client = new HttpClient();

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


// Specify the payment request ID
string paymentRequestID = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";

// neet to include authorizationID of transaction to void in request body
string authorizationID = "XXXXXXXXXXXXXXXXXXXXXX";

var postData = new StringContent($"authorizationID={authorizationID}", Encoding.UTF8, "application/x-www-form-urlencoded");

try
{
    HttpResponseMessage response = await client.PostAsync($"{baseUrl}/{paymentRequestID}/card/refund", postData);
    if (response.IsSuccessStatusCode)
    {
        // The card payment response model will be returned in JSON object.
        Console.WriteLine(await response.Content.ReadFromJsonAsync<CardResponse>());
    }
    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 CardResponse(string authorizedAmount, string currencyCode, string responseCode, string status,
                string requestID, string transactionID, CardError error, string payerAuthenticationUrl,
                string payerAuthenticationAccessToken, int payerAuthenticationWindowWidth,
                int payerAuthenticationWindowHeight );

record CardError(int errorCode, string id, string message, string reason, string status, string[] details, string rawResponse);
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_MERCHANT_TOKEN;

const baseUrl = 'https://api-sandbox.nofrixion.com/api/v1/paymentrequests';

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

// need to specify authorizationID of transaction to be voided
var form = new FormData();
form.append('authorizationID', 'XXXXXXXXXXXXXXXXXXXXXX');

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

fetch(`${baseUrl}/${paymentRequestID}/card/refund`, options)
    .then(response => response.json())
    // Card payment response model will be returned in JSON response object.
    .then(responseJson => 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)
# ... and when dealing with payment requests, use a MERCHANT token!
jwtToken = os.environ['NOFRIXION_MERCHANT_TOKEN']

baseUrl = "https://api-sandbox.nofrixion.com/api/v1/paymentrequests"
paymentRequestID = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

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

# need to specify authorizationID of transaction to be voided
postData = {
    "authorizationID": "XXXXXXXXXXXXXXXXXXXXXX"
}

try:
    response = requests.request("POST", f"{baseUrl}/{paymentRequestID}/card/refund", headers=headers, data=postData)

    if response.ok:
        #  On successful void, the API returns the card payment response model with 'status': 'VOIDED'
        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)