Invoices | Cancel Invoice

Invoice Cancellation Endpoint

This document provides guidance on using the API to cancel an invoice through the cancel_invoice endpoint. Cancellation mirrors the admin UI behaviour: an invoice that already has payment transactions cannot be cancelled (return an error instead of a silent cancel), linked orders are detached so they can be re-invoiced, and the invoice stays visible with status cancelled.

API ENDPOINT FOR INVOICE CANCELLATION

To cancel an invoice, provide your API credentials plus the numeric invoice_id or the payment reference number. An optional cancel_date can be sent; it defaults to today.

Endpoint and Method

  • Endpoint: https://easycms.fi/public_api/cancel_invoice/
  • Method: POST

Parameters | Payload

API Authentication Parameters

  • TOKEN (api_key): Your unique API key for authentication. How to Create API Credentials.
  • username: Your login username.
  • password: Your login password.
  • account: Your specific account ID.

Invoice Cancellation Parameters

  • invoice_id (integer): The numeric invoice id (either this or reference is required).
  • reference (string): The invoice payment reference number (either this or invoice_id is required).
  • cancel_date (optional): The cancellation date, Y-m-d or dd.mm.YYYY (default: today).

Handling Responses

On success the response echoes the invoice id, reference and the cancelled status. On refusal the response is an error envelope whose message explains why (most commonly existing transactions).



Call Examples in Different Languages


curl -X POST 'https://easycms.fi/public_api/cancel_invoice' \
-H 'Authorization1: TOKEN' \
-d 'username=USERNAME&password=PASSWORD&account=ACCOUNT_ID&invoice_id=1043'

$curl = curl_init();
curl_setopt_array($curl, array(
  CURLOPT_URL => "https://easycms.fi/public_api/cancel_invoice",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_POST => true,
  CURLOPT_POSTFIELDS => http_build_query(['username' => 'USERNAME', 'password' => 'PASSWORD', 'account' => 'ACCOUNT_ID', 'invoice_id' => '1043']),
  CURLOPT_HTTPHEADER => array("Authorization1: TOKEN"),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;

import requests
url = "https://easycms.fi/public_api/cancel_invoice"
headers = {"Authorization1": "TOKEN"}
payload = {'username': 'USERNAME', 'password': 'PASSWORD', 'account': 'ACCOUNT_ID', 'invoice_id': '1043'}
response = requests.post(url, headers=headers, data=payload)
print(response.text)

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://easycms.fi/public_api/cancel_invoice"))
    .headers("Authorization1", "TOKEN")
    .POST(HttpRequest.BodyPublishers.ofString("username=USERNAME&password=PASSWORD&account=ACCOUNT_ID&invoice_id=1043"))
    .build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());

const https = require('https');
const data = new URLSearchParams({ 
  "username": "USERNAME",
  "password": "PASSWORD",
  "account": "ACCOUNT_ID",
  "invoice_id": "1043",
}).toString();
const options = {
  hostname: 'easycms.fi',
  path: '/public_api/cancel_invoice',
  method: 'POST',
  headers: {
    'Authorization1': 'TOKEN',
    'Content-Type': 'application/x-www-form-urlencoded',
    'Content-Length': data.length
  }
};
const req = https.request(options, (res) => {
  let data = '';
  res.on('data', (chunk) => { data += chunk; });
  res.on('end', () => { console.log(data); });
});
req.on('error', (e) => { console.error(e); });
req.write(data);
req.end();

import React, { useEffect, useState } from 'react';
function App() {
  const [responseText, setResponseText] = useState('');
  useEffect(() => {
    const fetchData = async () => {
      try {
        const response = await fetch('https://easycms.fi/public_api/cancel_invoice', {
          method: 'POST',
          headers: {'Authorization1': 'TOKEN', 'Content-Type': 'application/x-www-form-urlencoded'},
          body: new URLSearchParams({"username": "USERNAME", "password": "PASSWORD", "account": "ACCOUNT_ID", "invoice_id": "1043"}).toString()
        });
        const data = await response.text();
        setResponseText(data);
      } catch (error) {
        console.error(error);
      }
    };
    fetchData();
  }, []);
  return (
{responseText}
); } export default App;

// Kotlin example requires using a third-party library like OkHttp for POST requests with a body
// Kotlin Example using OkHttp for POST request
import okhttp3.OkHttpClient
import okhttp3.FormBody
import okhttp3.Request

fun main() {
    val client = OkHttpClient()

    val formBody = FormBody.Builder()
        .add("username", "USERNAME")
        .add("password", "PASSWORD")
        .add("account", "ACCOUNT_ID")
        .add("invoice_id", "1043")
        .build()

    val request = Request.Builder()
        .url("https://easycms.fi/public_api/cancel_invoice")
        .post(formBody)
        .addHeader("Authorization1", "TOKEN")
        .build()

    client.newCall(request).execute().use { response ->
        if (!response.isSuccessful) throw IOException("Unexpected code $response")

        println(response.body?.string())
    }
}

using System;
using System.Net.Http;
using System.Threading.Tasks;
class Program
{
    static async Task Main()
    {
        var token = "TOKEN";
        var content = new FormUrlEncodedContent(new[]
        {
            new KeyValuePair("username", "USERNAME"),
            new KeyValuePair("password", "PASSWORD"),
            new KeyValuePair("account", "ACCOUNT_ID"),
            new KeyValuePair("invoice_id", "1043")
        });
        using (var httpClient = new HttpClient())
        {
            httpClient.DefaultRequestHeaders.Add("Authorization1", token);
            var response = await httpClient.PostAsync("https://easycms.fi/public_api/cancel_invoice", content);
            if (response.IsSuccessStatusCode)
            {
                var responseData = await response.Content.ReadAsStringAsync();
                Console.WriteLine(responseData);
            }
            else
            {
                Console.WriteLine($"Error: {response.StatusCode}");
            }
        }
    }
}

Handling Endpoint Results

When you make a request to the endpoint, you receive a JSON response containing various keys and values. Here's an explanation of the response keys and their meanings:


{
    "OUTPUT": {
        "response_type": "success",
        "message": "invoice_was_cancelled_successfully",
        "invoice": {
            "invoice_id": 1043,
            "reference": "10753108884421",
            "status": "cancelled"
        }
    },
    "INFO": { "start": 0, "limit": 50, "count": 1, "total_count": 1, "tip": "", "docs": "https://easycms.fi/DOCUMENTATION/bt5/cancel_invoice" }
}
    

Error Handling

Here are the possible error messages and their meanings:

  • invoice_id_or_reference_must_be_provided_via_api: Neither invoice_id nor reference was sent.
  • invoice_not_found: No live invoice matches the id/reference in this account.
  • invoice_is_already_cancelled: The invoice is already cancelled.
  • you_cannot_cancel_an_invoice_which_has_transactions_paid_or_partially_paid: The invoice has payment transactions and cannot be cancelled — the same guard the admin UI applies.
  • UN-AUTHORIZED - ...: Authentication failed (wrong TOKEN/username/password/account).