verifactu

package module
v0.11.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 30, 2025 License: AGPL-3.0 Imports: 11 Imported by: 0

README

GOBL to VeriFactu

Go library to convert GOBL invoices into VeriFactu declarations and send them to the AEAT (Agencia Estatal de Administración Tributaria) web services. This library assumes that clients will handle a local database of previous invoices in order to comply with the local requirements of chaining all invoices together.

Released under the Apache 2.0 LICENSE, Copyright 2021-2025 Invopop S.L..

Source

The main resources used in this module include:

Usage

Go Package

You must have first created a GOBL Envelope containing an Invoice that you'd like to send to the AEAT. For the document to be converted, the supplier contained in the invoice should have a "Tax ID" with the country set to ES.

The following is an example of how the GOBL VeriFactu package could be used:

package main

import (
	"context"
	"encoding/json"
	"fmt"
	"os"

	"github.com/invopop/gobl"
	verifactu "github.com/invopop/gobl.verifactu"
	"github.com/invopop/gobl.verifactu/doc"
	"github.com/invopop/xmldsig"
)

func main() {
	ctx := context.Background()

	// Load sample envelope:
	data, _ := os.ReadFile("./test/data/sample-invoice.json")
	env := new(gobl.Envelope)
	if err := json.Unmarshal(data, env); err != nil {
		panic(err)
	}

	// VeriFactu requires a software definition to be provided. This is an example
	software := &verifactu.Software{
		NombreRazon:              "Company LTD",    // Company Name
		NIF:                      "B123456789",     // Software company's tax code
		NombreSistemaInformatico: "Software Name",  // Name of application
		IdSistemaInformatico:     "A1",             // Software ID
		Version:                  "1.0",            // Software version
		NumeroInstalacion:        "00001",          // Software installation number
	}

	// Load the certificate
	cert, err := xmldsig.LoadCertificate(
		"./path/to/certificate.p12",
		"password",
	)
	if err != nil {
		panic(err)
	}

	// Create the client with the software and certificate
	opts := []verifactu.Option{
		verifactu.WithCertificate(cert),
		verifactu.WithSupplierIssuer(), // The issuer can be either the supplier, the customer or a third party
		verifactu.InTesting(),          // Use the testing environment, as the production endpoint is not yet published
	}

	tc, err := verifactu.New(software, opts...)
	if err != nil {
		panic(err)
	}

	// Convert the GOBL envelope to a VeriFactu document
	td, err := tc.Convert(env)
	if err != nil {
		panic(err)
	}

	// Prepare the previous document chain data
	previous, err := os.ReadFile("./path/to/previous_invoice.json")
	if err != nil {
		panic(err)
	}

	prev := new(doc.ChainData)
	if err := json.Unmarshal([]byte(previous), prev); err != nil {
		panic(err)
	}

	// Create the document fingerprint based on the previous document chain
	err = tc.Fingerprint(td, prev)
	if err != nil {
		panic(err)
	}

	// Add the QR code to the document
	if err := tc.AddQR(td, env); err != nil {
		panic(err)
	}

	// Send the document to the tax agency
	err = tc.Post(ctx, td)
	if err != nil {
		panic(err)
	}

	// Print the data to be used as previous document chain for the next invoice
	// Persist the data somewhere to be used by the next invoice
	cd, err := json.Marshal(td.ChainData())
	if err != nil {
		panic(err)
	}
	fmt.Printf("Generated document with fingerprint: \n%s\n", string(cd))

}
Command Line

The GOBL VeriFactu package tool also includes a command line helper. You can install manually in your Go environment with:

go install github.com/invopop/gobl.verifactu

We recommend using a .env file to prepare configuration settings, although all parameters can be set using command line flags. Heres an example:

SOFTWARE_COMPANY_NIF=B85905495
SOFTWARE_COMPANY_NAME=Invopop S.L.
SOFTWARE_NAME=gobl.verifactu
SOFTWARE_VERSION=1.0
SOFTWARE_ID_SISTEMA_INFORMATICO=A1
SOFTWARE_NUMERO_INSTALACION=00001
DEBUG=true
CERTIFICATE_PATH=xxxxxxxxx
CERTIFICATE_PASSWORD=xxxxxxxxx

To convert a document to XML, run:

gobl.verifactu convert ./test/data/sample-invoice.json

This function will output the XML to the terminal, or to a file if a second argument is provided. The output file will not include a fingerprint, and therefore will not be able to be submitted to the tax agency.

To submit to the tax agency testing environment:

gobl.verifactu send ./test/data/sample-invoice.json ./test/data/previous-invoice-info.json

Now, the output file will include a fingerprint, linked to the previous document, and will be submitted to the tax agency. An example for a previous file would look like this:

{
  "emisor": "B12345678",
  "serie": "SAMPLE-001",
  "fecha": "2024-11-28",
  "huella": "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF"
}

Tags and Extensions

In order to provide the supplier specific data required by VeriFactu, invoices need to include a bit of extra data. We've managed to simplify these into specific cases.

Invoice Tags

Invoice tax tags can be added to invoice documents in order to reflect a special situation. The following schemes are supported:

  • simplified - a retailer operating under a simplified tax regime (regimen simplificado). This implies that all operations in the invoice will have the FacturaSinIdentifDestinatarioArt61d tag set to S and the TipoFactura field set to F2. For corrective invoices, and credit and debit notes, the TipoFactura should instead be set to R5 through the es-verifactu-doc-type extension.
Tax Extensions

The following extensions must be included in the document. Note that the GOBL addon will automatically add these extensions when processing invoices:

  • es-verifactu-doc-type – defines the type of invoice being sent. In most cases this will be set automatically by GOBL, but it must be present. It is taken from list L2 of the VeriFactu Ministerial Order. These are the valid values:

    • F1 - Standard invoice.
    • F2 - Simplified invoice.
    • F3 - Invoice in substitution of simplified invoices.
    • R1 - Rectified invoice based on law and Article 80.1, 80.2 and 80.6 in the Spanish VAT Law.
    • R2 - Rectified invoice based on law and Article 80.3.
    • R3 - Rectified invoice based on law and Article 80.4.
    • R4 - Rectified invoice based on law and other reasons.
    • R5 - Rectified invoice based on simplified invoices.
  • es-verifactu-op-class - Operation classification code used to identify if taxes should be applied to the line. It is taken from list L9 of the VeriFactu Ministerial Order. These are the valid values:

    • S1 - Subject and not exempt - Without reverse charge
    • S2 - Subject and not exempt - With reverse charge. Known as Inversión del Sujeto Pasivo in Spanish VAT Law
    • N1 - Not subject - Articles 7, 14, others
    • N2 - Not subject - Due to location rules
  • es-verifactu-exempt - Exemption code used to identify if the line item is exempt from taxes. It is taken from list L10 of the VeriFactu Ministerial Order. These are the valid values:

    • E1 - Exempt pursuant to Article 20 of the VAT Law
    • E2 - Exempt pursuant to Article 21 of the VAT Law
    • E3 - Exempt pursuant to Article 22 of the VAT Law
    • E4 - Exempt pursuant to Articles 23 and 24 of the VAT Law
    • E5 - Exempt pursuant to Article 25 of the VAT Law
    • E6 - Exempt for other reasons
  • es-verifactu-correction-type - Differentiates between the correction method. Corrective invoices in VeriFactu can be Facturas Rectificativas por Diferencias or Facturas Rectificativas por Sustitución. It is taken from list L3 of the VeriFactu Ministerial Order. These are the valid values:

    • I - Differences. Used for credit and debit notes. In case of credit notes the values of the invoice are inverted to reflect the amount being a credit instead of a debit.
    • S - Substitution. Used for corrective invoices.
  • es-verifactu-regime - Regime code used to identify the type of VAT/IGIC regime to be applied to the invoice. It combines the values of lists L8A and L8B of the VeriFactu Ministerial Order. These are the valid values:

    • 01 - General regime operation
    • 02 - Export
    • 03 - Special regime for used goods, art objects, antiques and collectibles
    • 04 - Special regime for investment gold
    • 05 - Special regime for travel agencies
    • 06 - Special regime for VAT/IGIC groups (Advanced Level)
    • 07 - Special cash accounting regime
    • 08 - Operations subject to a different regime
    • 09 - Billing of travel agency services acting as mediators in name and on behalf of others
    • 10 - Collection of professional fees or rights on behalf of third parties
    • 11 - Business premises rental operations
    • 14 - Invoice with pending VAT/IGIC accrual in work certifications for Public Administration
    • 15 - Invoice with pending VAT/IGIC accrual in successive tract operations
    • 17 - Operation under OSS and IOSS regimes (VAT) / Special regime for retail traders. (IGIC)
    • 18 - Equivalence surcharge (VAT) / Special regime for small traders or retailers (IGIC)
    • 19 - Operations included in the Special Regime for Agriculture, Livestock and Fisheries
    • 20 - Simplified regime (VAT only)

Limitations

  • VeriFactu allows more than one customer per invoice, but GOBL only has one possible customer.
  • Invoices must have a note of type general that will be used as a general description of the invoice. If an invoice is missing this info, it will be rejected with an error.
  • VeriFactu supports sending more than one invoice at a time (up to 1000). However, this module only currently supports 1 invoice at a time.
  • VeriFactu requires a valid certificate to be provided, even when using the testing environment. It is the same certificate needed to access the AEAT's portal.
  • When cancelling invoices, this module assumes the party issuing the cancellation is the same as the party that issued the original invoice. In the context of the app this would always be true, but VeriFactu does allow for a different issuer.

Testing

This library includes a set of tests that can be used to validate the conversion and submission process. To run the tests, use the following command:

go test ./...

Some sample test data is available in the ./test directory. To update the JSON documents and regenerate the XML files for testing, use the following command:

go test --update

Documentation

Overview

Package verifactu provides the VeriFactu client

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client provides the main interface to the VeriFactu package.

func New

func New(software *doc.Software, opts ...Option) (*Client, error)

New creates a new VeriFactu client with shared software and configuration options for creating and sending new documents.

func (*Client) AddQR

func (c *Client) AddQR(d *doc.Envelope, env *gobl.Envelope) error

AddQR adds the QR code stamp to the envelope.

func (*Client) Convert

func (c *Client) Convert(env *gobl.Envelope) (*doc.Envelope, error)

Convert creates a new document from the provided GOBL Envelope. The envelope must contain a valid Invoice.

func (*Client) CurrentTime

func (c *Client) CurrentTime() time.Time

CurrentTime returns the current time to use when generating the VeriFactu document.

func (*Client) Fingerprint

func (c *Client) Fingerprint(d *doc.Envelope, prev *doc.ChainData) error

Fingerprint generates a fingerprint for the document using the data provided from the previous chain data. If there was no previous document in the chain, the parameter should be nil. The document is updated in place.

func (*Client) FingerprintCancel

func (c *Client) FingerprintCancel(d *doc.Envelope, prev *doc.ChainData) error

FingerprintCancel generates a fingerprint for the cancellation document using the data provided from the previous chain data. The document is updated in place.

func (*Client) GenerateCancel

func (c *Client) GenerateCancel(env *gobl.Envelope) (*doc.Envelope, error)

GenerateCancel creates a new cancellation document from the provided GOBL Envelope.

func (*Client) Post

func (c *Client) Post(ctx context.Context, d []byte) error

Post will send the document to the VeriFactu gateway.

func (*Client) Sandbox

func (c *Client) Sandbox() bool

Sandbox returns true if the client is using the sandbox environment.

type Option

type Option func(*Client)

Option is used to configure the client.

func InProduction

func InProduction() Option

InProduction defines the connection to use the production environment.

func InSandbox

func InSandbox() Option

InSandbox defines the connection to use the testing environment.

func WithCertificate

func WithCertificate(cert *xmldsig.Certificate) Option

WithCertificate defines the signing certificate to use when producing the VeriFactu document.

func WithCurrentTime

func WithCurrentTime(curTime time.Time) Option

WithCurrentTime defines the current time to use when generating the VeriFactu document. Only useful for testing.

func WithCustomerIssuer

func WithCustomerIssuer() Option

WithCustomerIssuer set the issuer type to customer.

func WithRepresentative added in v0.3.0

func WithRepresentative(name, nif string) Option

WithRepresentative can be used to define a legal representative of the entity legally obliged to issue the invoice, usually the supplier. This may be required when the supplier's digital certificate is not available.

func WithSupplierIssuer

func WithSupplierIssuer() Option

WithSupplierIssuer set the issuer type to supplier.

func WithThirdPartyIssuer

func WithThirdPartyIssuer() Option

WithThirdPartyIssuer set the issuer type to third party.

Directories

Path Synopsis
cmd
gobl.verifactu command
Package main provides the command line interface to the VeriFactu package.
Package main provides the command line interface to the VeriFactu package.
Package doc provides the VeriFactu document mappings from GOBL
Package doc provides the VeriFactu document mappings from GOBL
internal
gateways
Package gateways provides the VeriFactu gateway
Package gateways provides the VeriFactu gateway
Package test provides common functions for testing.
Package test provides common functions for testing.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL