Void a receipt

This tutorial demonstrates how to handle the voiding of a sale receipt.
You'll learn how to:

  • Void a sale receipt issued by the same Point of Sale you are operating from
  • Void a sale receipt issued by a different Point of Sale
  • Void a sale receipt that hasn't been issued by a Point of Sale

Prerequisites

Receipts can be issued only by a merchant or a cashier with a valid certificate (PEM file).

Case 1: Void a sale receipt issued by the same Point of Sale

Since our goal is to void a sale receipt, we will first issue one from a cash register associated to the Point of Sale E001-000001 and use it as reference:

PythonJavaScriptBashPHP
Copy
Copied
import requests

CERT_PATH = '/var/certs/pos/E001-000001/cashregister.pem'
KEY_PATH = '/var/certs/pos/E001-000001/cashregister.pem'
response = requests.post(
    'https://ereceipts-it-sandbox.acubeapi.com:444/mf1/receipt',
    cert=(CERT_PATH, KEY_PATH),
    json={
    "electronic_payment_amount": "122",
		"items": [
      {
        "type": "goods",
        "quantity": "1",
        "description": "Product",
        "unit_price": "122",
        "vat_rate_code": "22"
      }
    ]
  }
)
Copy
Copied
const fs = require('fs');
const https = require('https');

const CERT = fs.readFileSync('/var/certs/pos/E001-000001/cashregister.pem')
const KEY = fs.readFileSync('/var/certs/pos/E001-000001/cashregister.pem')
const req = https.request(
  {
    hostname: 'ereceipts-it-sandbox.acubeapi.com',
    headers: {
      "Content-Type": "application/json"
    },
    port: 444,
    path: '/mf1/receipt',
    method: 'POST',
    cert: CERT,
    key: KEY
  },
  res => {
    let body = '';
    res.on('data', function(data) {
      body += data;
    });
    res.on('end', function() {
      console.log(body);
    })
  }
);
req.write(JSON.stringify({
  "electronic_payment_amount": "122",
  "items": [
     {
        "type": "goods",
        "quantity": "1",
        "description": "Product",
        "unit_price": "122",
        "vat_rate_code": "22"
      }
  ]
}));
req.end();
Copy
Copied
curl -X POST https://ereceipts-it-sandbox.acubeapi.com:444/mf1/receipt  \
-H 'Content-Type: application/json' \
-d '{"electronic_payment_amount":"122","items":[{"type":"goods","quantity":"1","description":"Product","unit_price":"122","vat_rate_code":"22"}]}' \
--cert /var/certs/pos/E001-000001/cashregister.pem \
--key /var/certs/pos/E001-000001/cashregister.pem
Copy
Copied
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://ereceipts-it-sandbox.acubeapi.com:444/mf1/receipt');
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode('{
    "electronic_payment_amount": "122",
    "items": [
       {
        "type": "goods",
        "quantity": "1",
        "description": "Product",
        "unit_price": "122",
        "vat_rate_code": "22"
      }
    ]
}'));
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type:application/json']);
curl_setopt($ch, CURLOPT_SSLCERT, '/var/certs/pos/E001-000001/cashregister.pem');
curl_setopt($ch, CURLOPT_SSLKEY, '/var/certs/pos/E001-000001/cashregister.pem');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);

You will receive a 201 status code and the following response body:

Copy
Copied
{
  "uuid": "18a681da-a868-47ba-a931-2f702474c3d1",
  "type": "sale",
  "total_amount": "122",
  "document_number": "0001-0001",
  "document_datetime": "2025-09-01T10:00:00",
  "parent_receipt_uuid": null
}

Now that we have a sale receipt, we can void it using a simple DELETE request since we are operating from the same Point of Sale that issued it:

PythonJavaScriptBashPHP
Copy
Copied
import requests

CERT_PATH = '/var/certs/pos/E001-000001/cashregister.pem'
KEY_PATH = '/var/certs/pos/E001-000001/cashregister.pem'
response = requests.delete(
    'https://ereceipts-it-sandbox.acubeapi.com:444/mf1/receipt',
    cert=(CERT_PATH, KEY_PATH),
    json={
      "document_number": "0001-0001"
    }
)
Copy
Copied
const fs = require('fs');
const https = require('https');

const CERT = fs.readFileSync('/var/certs/pos/E001-000001/cashregister.pem')
const KEY = fs.readFileSync('/var/certs/pos/E001-000001/cashregister.pem')
const req = https.request(
  {
    hostname: 'ereceipts-it-sandbox.acubeapi.com',
    headers: {
      "Content-Type": "application/json"
    },
    port: 444,
    path: '/mf1/receipt',
    method: 'DELETE',
    cert: CERT,
    key: KEY
  },
  res => {
    let body = '';
    res.on('data', function(data) {
      body += data;
    });
    res.on('end', function() {
      console.log(body);
    })
  }
);
req.write(JSON.stringify({
    "document_number": "0001-0001"
}));
req.end();
Copy
Copied
curl -X DELETE https://ereceipts-it-sandbox.acubeapi.com:444/mf1/receipt  \
-H 'Content-Type: application/json' \
-d '{"document_number":"0001-0001"}' \
--cert /var/certs/pos/E001-000001/cashregister.pem \
--key /var/certs/pos/E001-000001/cashregister.pem
Copy
Copied
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://ereceipts-it-sandbox.acubeapi.com:444/mf1/receipt');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode('{
    "document_number": "0001-0001"
}'));
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type:application/json']);
curl_setopt($ch, CURLOPT_SSLCERT, '/var/certs/pos/E001-000001/cashregister.pem');
curl_setopt($ch, CURLOPT_SSLKEY, '/var/certs/pos/E001-000001/cashregister.pem');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);

The HTTP response will have status code 204 and no content.

Case 2: Void a sale receipt issued by a different Point of Sale

If you need to void a sale receipt that was issued by a different Point of Sale, you need to make a DELETE request to /mf1/receipts/void-via-different-pos.
For example, if you want to void the sale receipt previously issued by the Point of Sale E001-000001 from the Point of Sale E001-000002, you would do the following:

PythonJavaScriptBashPHP
Copy
Copied
import requests

CERT_PATH = '/var/certs/pos/E001-000002/cashregister.pem'
KEY_PATH = '/var/certs/pos/E001-000002/cashregister.pem'
response = requests.delete(
    'https://ereceipts-it-sandbox.acubeapi.com:444/mf1/receipts/void-via-different-pos',
    cert=(CERT_PATH, KEY_PATH),
    json={
      "pos_id": "E001-000001",
      "document_number": "0001-0001",
      "document_datetime": "2025-09-01T10:00",
      "items": [
        {
          "type": "goods",
          "quantity": "1",
          "description": "Product",
          "unit_price": "122",
          "vat_rate_code": "22"
        }
      ]
    }
)
Copy
Copied
const fs = require('fs');
const https = require('https');

const CERT = fs.readFileSync('/var/certs/pos/E001-000002/cashregister.pem')
const KEY = fs.readFileSync('/var/certs/pos/E001-000002/cashregister.pem')
const req = https.request(
  {
    hostname: 'ereceipts-it-sandbox.acubeapi.com',
    headers: {
      "Content-Type": "application/json"
    },
    port: 444,
    path: '/mf1/receipts/void-via-different-pos',
    method: 'DELETE',
    cert: CERT,
    key: KEY
  },
  res => {
    let body = '';
    res.on('data', function(data) {
      body += data;
    });
    res.on('end', function() {
      console.log(body);
    })
  }
);
req.write(JSON.stringify({
    "pos_id": "E001-000001",
    "document_number": "0001-0001",
    "document_datetime": "2025-09-01T10:00",
    "items": [
      {
        "type": "goods",
        "quantity": "1",
        "description": "Product",
        "unit_price": "122",
        "vat_rate_code": "22"
      }
    ]
}));
req.end();
Copy
Copied
curl -X DELETE https://ereceipts-it-sandbox.acubeapi.com:444/mf1/receipts/void-via-different-pos  \
-H 'Content-Type: application/json' \
-d '{"pos_id": "E001-0001", "document_number":"0001-0001", "document_datetime": "2025-09-01T10:00", "items":[{"type":"goods","quantity":"1","description":"Product","unit_price":"122","vat_rate_code":"22"}]}' \
--cert /var/certs/pos/E001-000002/cashregister.pem \
--key /var/certs/pos/E001-000002/cashregister.pem
Copy
Copied
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://ereceipts-it-sandbox.acubeapi.com:444/mf1/receipts/void-via-different-pos');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode('{
    "pos_id": "E001-0001",
    "document_number": "0001-0001",
    "document_datetime": "2025-09-01T10:00",
    "items": [
      {
        "type": "goods",
        "quantity": "1",
        "description": "Product",
        "unit_price": "122",
        "vat_rate_code": "22"
      }
    ]
}'));
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type:application/json']);
curl_setopt($ch, CURLOPT_SSLCERT, '/var/certs/pos/E001-000002/cashregister.pem');
curl_setopt($ch, CURLOPT_SSLKEY, '/var/certs/pos/E001-000002/cashregister.pem');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);

The HTTP response will have status code 204 and no content.

Case 3: Sale receipt not issued by a Point of Sale

It might be that the sale receipt has not been issued by a Point of Sale, so it is not possible to specify a document_number. In this case you should make a POST request to /mf1/receipts/void-with-proof:

PythonJavaScriptBashPHP
Copy
Copied
import requests

CERT_PATH = '/var/certs/pos/E001-000001/cashregister.pem'
KEY_PATH = '/var/certs/pos/E001-000001/cashregister.pem'
response = requests.post(
  'https://ereceipts-it-sandbox.acubeapi.com:444/mf1/receipt/void-with-proof',
  cert=(CERT_PATH, KEY_PATH),
  json= {
    "items": [
      {
        "type": "goods",
        "quantity": "1",
        "description": "Product",
        "unit_price": "122",
        "vat_rate_code": "22"
      }
    ],
    "proof": "POS",
    "document_datetime": "2025-09-01T10:00:00"
  }
)
Copy
Copied
const fs = require('fs');
const https = require('https');

const CERT = fs.readFileSync('/var/certs/pos/E001-000001/cashregister.pem')
const KEY = fs.readFileSync('/var/certs/pos/E001-000001/cashregister.pem')
const req = https.request(
  {
    hostname: 'ereceipts-it-sandbox.acubeapi.com',
    headers: {
      "Content-Type": "application/json"
    },
    port: 444,
    path: '/mf1/receipt/void-with-proof',
    method: 'POST',
    cert: CERT,
    key: KEY
  },
  res => {
    let body = '';
    res.on('data', function(data) {
      body += data;
    });
    res.on('end', function() {
      console.log(body);
    })
  }
);
req.write(JSON.stringify( {
    "items": [
      {
        "type": "goods",
        "quantity": "1",
        "description": "Product",
        "unit_price": "122",
        "vat_rate_code": "22"
      }
    ],
    "proof": "POS",
    "document_datetime": "2025-09-01T10:00:00"
}));
req.end();
Copy
Copied
curl -X POST https://ereceipts-it-sandbox.acubeapi.com:444/mf1/receipt/void-with-proof  \
-H 'Content-Type: application/json' \
-d '{"items":[{"good_or_service":"B","quantity":"1","description":"Product","unit_price":"122","vat_rate_code":"22"}],"proof":"POS","document_datetime":"2025-09-01T10:00:00"}' \
--cert /var/certs/pos/E001-000001/cashregister.pem \
--key /var/certs/pos/E001-000001/cashregister.pem
Copy
Copied
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://ereceipts-it-sandbox.acubeapi.com:444/mf1/receipt/void-with-proof');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode('{
    "items": [
      {
        "type": "goods",
        "quantity": "1",
        "description": "Product",
        "unit_price": "122",
        "vat_rate_code": "22"
      }
    ],
    "proof": "POS",
    "document_datetime": "2025-09-01T10:00:00"
}'));
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type:application/json']);
curl_setopt($ch, CURLOPT_SSLCERT, '/var/certs/pos/E001-000001/cashregister.pem');
curl_setopt($ch, CURLOPT_SSLKEY, '/var/certs/pos/E001-000001/cashregister.pem');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);
info

the field proof can be set to one of "POS", "VR" (vuoti a rendere), or "ND" (non definito). "POS" in this case refers to a payment processing device, not the Point of Sale entity referred to in this documentation.