Skip to content

Invoice Signing

How to sign UBL invoices with a CSID certificate and private key.

Example

pub fn main() {
    use fatoora_core::invoice::sign::invoice_hash_base64_from_xml_str;
    use fatoora_core::invoice::xml::parse::parse_signed_invoice_xml;

    let signed_xml_path = std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
        .join("tests/fixtures/invoices/sample-simplified-invoice.xml");
    let signed_xml =
        std::fs::read_to_string(&signed_xml_path).expect("read signed invoice xml");
    let signed = parse_signed_invoice_xml(&signed_xml).expect("parse signed invoice");

    let hash = invoice_hash_base64_from_xml_str(&signed_xml).expect("compute invoice hash");
    let qr = signed.qr_code();
    let signing_time = signed.signed_properties().signing_time();
    assert!(!hash.is_empty());
    assert!(!qr.is_empty());
    let _ = signing_time;
}
from fatoora.invoice import parse_signed_invoice_xml

# signed_xml_path = "path/to/signed_invoice.xml"
signed_xml = signed_xml_path.read_text(encoding="utf-8")

signed = parse_signed_invoice_xml(signed_xml)

hash_b64 = signed.hash_base64()
qr = signed.qr()
signing_time = signed.signing_time()
assert hash_b64
assert qr
#include "fatoora/invoice.h"
#include "fatoora/sign.h"

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifndef FATOORA_DOC_SIGNED_XML
#define FATOORA_DOC_SIGNED_XML "path/to/signed_invoice.xml"
#endif

static char *read_file(const char *path);

int main(void) {
    const char *signed_xml_path = FATOORA_DOC_SIGNED_XML;
    char *xml_cstr = read_file(signed_xml_path);
    if (!xml_cstr) {
        /* handle error */
        return 1;
    }

    /* signed_xml_path = "path/to/signed_invoice.xml" */
    struct FfiResult_FfiSignedInvoice signed_invoice = fatoora_parse_signed_invoice_xml(xml_cstr);
    if (!signed_invoice.ok) {
        /* handle error */
        return 1;
    }
    struct FfiResult_FfiString hash = fatoora_signed_invoice_hash_base64(&signed_invoice.value);
    struct FfiResult_FfiString qr = fatoora_signed_invoice_qr(&signed_invoice.value);
    assert(hash.value.ptr && strlen(hash.value.ptr) > 0);
    assert(qr.value.ptr && strlen(qr.value.ptr) > 0);
    fatoora_string_free(hash.value);
    fatoora_string_free(qr.value);
    free(xml_cstr);
    fatoora_signed_invoice_free(&signed_invoice.value);
    return 0;
}

Notes

  • Signed invoice metadata (signature/public key/signed props hashes) are exposed as getters.
  • Prefer string-based XML inputs; the library does not read files for you.

See also: Invoice Signing Reference