Void a receipt

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

  • Issue a void receipt for a sale receipt issued by the same Point of Sale or a different one
  • Issue a void receipt associated to a sale receipt that hasn't been issued by a Point of Sale.

Case 1: Sale receipt issued by a Point of Sale

Prerequisites

Receipts can be issued only by a merchant or a cashier with a valid certificate (PEM file).
Since our goal is to void a sale receipt, we will issue one from a cash register associated to the Point of Sale E001-000001:

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": "244",
		"items": [
      {
        "good_or_service": "B",
        "quantity": "1",
        "description": "Product",
        "unit_price": "100",
        "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({
  "items": [
     {
        "good_or_service": "B",
        "quantity": "1",
        "description": "Product",
        "unit_price": "100",
        "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":"244","items":[{"good_or_service":"B","quantity":"1","description":"Product","unit_price":"100","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": "244",
    "items": [
       {
        "good_or_service": "B",
        "quantity": "1",
        "description": "Product",
        "unit_price": "100",
        "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 the following response:

Copy
Copied
Response 201

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

Issue the void receipt

Supposing you are working from a cash register associated to the Point of Sale E001-000002 and you need to void the sale receipt above, you'd need to make the following HTTP request:

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/receipt',
    cert=(CERT_PATH, KEY_PATH),
    json={
      "pem_id": "E001-0001",
      "document_number": "0001-0001",
      "document_datetime": "2025-09-01T10:00"
    }
)
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/receipt/return',
    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( {
      "pem_id": "E001-0001",
      "document_number": "0001-0001",
      "document_datetime": "2025-09-01T10:00"
        }));
req.end();
Copy
Copied
curl -X DELETE https://ereceipts-it-sandbox.acubeapi.com:444/mf1/receipt  \
-H 'Content-Type: application/json' \
-d '{"pem_id": "E001-0001", "document_number":"0001-0001", "document_datetime": "2025-09-01T10:00"}' \
--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/receipt');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode('{
        "pem_id": "E001-0001",
        "document_number": "0001-0001",
        "document_datetime": "2025-09-01T10:00"
        }'));
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.

info

If the void receipt is issued by the same Point of Sale that issued the sale receipt, you can avoid to specify the pem_id in the request. If you specify it, the request will still be processed correctly as long as the cash register from which you are working is associated to the specified Point of Sale. You can also avoid to specify document_datetime, since it will be retrieved automatically by the system.

Case 2: 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.delete(
  'https://ereceipts-it-sandbox.acubeapi.com:444/mf1/receipt/void-with-proof',
  cert=(CERT_PATH, KEY_PATH),
  json= {
    "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"
  }
)
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: '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( {
    "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"
}));
req.end();
Copy
Copied
curl -X DELETE 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_CUSTOMREQUEST, "DELETE");
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode('{
    "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"
}'));
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

This endpoint requires the date and time of the original sales receipt, along with all items listed on that receipt.

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.