Skip to main content

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 PEM you are operating from
  • Void a sale receipt issued by a different PEM
  • Void a sale receipt that hasn't been issued by a PEM

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 PEM

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

import requests

CERT_PATH = '/var/certs/pems/E001-000001/cr-cert.pem'
KEY_PATH = '/var/certs/pems/E001-000001/cr-key.pem'
response = requests.post(
'https://ereceipts-it-sandbox.acubeapi.com:444/mf1/receipts',
cert=(CERT_PATH, KEY_PATH),
headers={
"Authorization": "Bearer <Merchant JWT Token>",
"Content-Type": "application/json"
},
json={
"electronic_payment_amount": "122",
"items": [
{
"type": "goods",
"quantity": "1",
"description": "Product",
"unit_price": "122",
"vat_rate_code": "22"
}
]
}
)

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

{
"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,
"is_voidable": true,
"is_returnable": true,
"html_url": "url/to/html",
"pdf_url": "url/to/pdf"
}

Now that we have a sale receipt, we can void it using a DELETE request on mf1/receipts since we are operating from the same PEM that issued it:

import requests

CERT_PATH = '/var/certs/pems/E001-000001/cer-cert.pem'
KEY_PATH = '/var/certs/pems/E001-000001/cer-key.pem'
response = requests.delete(
'https://ereceipts-it-sandbox.acubeapi.com:444/mf1/receipts',
cert=(CERT_PATH, KEY_PATH),
json={
"document_number": "0001-0001"
}
)

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

Case 2: Void a sale receipt issued by a different PEM

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

import requests

CERT_PATH = '/var/certs/pems/E001-000002/cr-cert.pem'
KEY_PATH = '/var/certs/pems/E001-000002/cr-key.pem'
response = requests.delete(
'https://ereceipts-it-sandbox.acubeapi.com:444/mf1/receipts/void-via-different-device',
cert=(CERT_PATH, KEY_PATH),
headers={
"Authorization": "Bearer <Merchant JWT Token>",
"Content-Type": "application/json"
},
json={
"device_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"
}
]
}
)

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

Case 3: Sale receipt not issued by a PEM

It might be that the sale receipt has not been issued by a PEM, 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:

import requests

CERT_PATH = '/var/certs/pems/E001-000001/cr-cert.pem'
KEY_PATH = '/var/certs/pems/E001-000001/cr-key.pem'
response = requests.post(
'https://ereceipts-it-sandbox.acubeapi.com:444/mf1/receipts/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"
}
)
info

the field proof can be set to one of "POS", "VR" (vuoti a rendere), or "ND" (non definito).