### Install GOBL Verifactu Library Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/15-quick-start.md Use the go get command to install the library. This is a standard Go package installation. ```bash go get github.com/invopop/gobl.verifactu ``` -------------------------------- ### Minimum Working Example for Invoice Registration Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/15-quick-start.md This example demonstrates the essential steps for registering and sending an invoice using the Verifactu client. It includes loading a certificate, configuring the software, creating a client, loading a GOBL invoice, registering it, creating a request, sending it to AEAT, and processing the response. Ensure you have a valid certificate file (cert.p12) and an invoice file (invoice.json) in the same directory. ```go package main import ( "context" "encoding/json" "fmt" "os" "github.com/invopop/gobl" verifactu "github.com/invopop/gobl.verifactu" "github.com/invopop/xmldsig" ) func main() { ctx := context.Background() // 1. Load certificate cert, err := xmldsig.LoadCertificate("./cert.p12", "password") if err != nil { panic(err) } // 2. Configure software software := &verifactu.Software{ NombreRazon: "Company S.L.", NIF: "B123456789", NombreSistemaInformatico: "MyApp", IdSistemaInformatico: "A1", Version: "1.0", NumeroInstalacion: "00001", } // 3. Create client client, err := verifactu.New(software, verifactu.WithCertificate(cert), verifactu.InSandbox(), // Use testing environment ) if err != nil { panic(err) } // 4. Load GOBL invoice env := new(gobl.Envelope) data, _ := os.ReadFile("invoice.json") json.Unmarshal(data, env) inv := env.Extract().(*gobl.bill.Invoice) // 5. Register invoice (first in chain) reg, err := client.RegisterInvoice(env, nil) if err != nil { panic(err) } // 6. Create request req, err := client.NewInvoiceRequest(inv.Supplier) if err != nil { panic(err) } req.AddRegistration(reg) // 7. Send to AEAT resp, err := client.SendInvoiceRequest(ctx, req) if err != nil { panic(err) } // 8. Check result for _, line := range resp.Lines { if err := line.Error(); err != nil { fmt.Printf("Error: %v\n", err) } else { fmt.Printf("Success: %s\n", line.Message()) // Save chain data for next invoice cd := line.ChainData() cdJSON, _ := json.Marshal(cd) os.WriteFile("chain.json", cdJSON, 0644) } } } ``` -------------------------------- ### Register System Startup Event Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/13-noverifactu-events.md Example of creating and registering a system startup event. Includes validation before registration. ```go status := &bill.Status{ UUID: uuid.New().String(), Issued: time.Now(), Provider: "software-name", Status: "event", Lines: []*bill.StatusLine{ { Key: noverifactu.KeySystemStartup, Description: "System started by user", }, }, } env := &gobl.Envelope{ Head: &head.Header{}, Document: status, } // Validate if faults := noverifactu.Validate(status); faults != nil { return faults.Error() } // Register event eventReg, err := client.RegisterEvent(env, nil) if err != nil { panic(err) } ``` -------------------------------- ### Install GOBL VeriFactu CLI Source: https://github.com/invopop/gobl.verifactu/blob/main/README.md Install the GOBL VeriFactu command line tool using the go install command. Ensure your Go environment is set up correctly. ```bash go install github.com/invopop/gobl.verifactu ``` -------------------------------- ### Example of Setting Code and Message Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/08-errors.md Demonstrates chaining `WithCode` and `WithMessage` to create a new error with specific details. ```go err := verifactu.ErrValidation.WithCode("001").WithMessage("Invalid amount") ``` -------------------------------- ### VeriFactu Client Initialization Example Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/01-client.md Demonstrates how to create a new VeriFactu client instance. It shows setting up software details, loading a certificate, and applying options like sandbox mode. ```go software := &verifactu.Software{ NombreRazon: "Company S.L.", NIF: "B123456789", NombreSistemaInformatico: "Software Name", IdSistemaInformatico: "A1", Version: "1.0", NumeroInstalacion: "00001", } cert, err := xmldsig.LoadCertificate("./cert.p12", "password") if err != nil { panic(err) } opts := []verifactu.Option{ verifactu.WithCertificate(cert), verifactu.InSandbox(), } client, err := verifactu.New(software, opts...) if err != nil { panic(err) } ``` -------------------------------- ### Example: Using newParty Function Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/11-party-identification.md Demonstrates how to use the newParty function to create a Party object from a GOBL org.Party and check if it can be included in a registration. ```go customer := invoice.Customer // GOBL org.Party pty := newParty(customer, invoice.IssueDate) if pty != nil { // Party can be included in registration } ``` -------------------------------- ### Complete Signed Submission with Verifactu Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/12-document-signing.md This example demonstrates a full workflow: loading a certificate, creating a Verifactu client with auto-signing enabled, loading an invoice, registering it, preparing a request, sending it to AEAT, and checking the response. ```go package main import ( "context" "encoding/json" "os" "github.com/invopop/gobl" verifactu "github.com/invopop/gobl.verifactu" "github.com/invopop/xmldsig" ) func main() { // Load certificate cert, err := xmldsig.LoadCertificate("./cert.p12", "password") if err != nil { panic(err) } // Create client with signing enabled software := &verifactu.Software{ NombreRazon: "MyCompany", NIF: "B12345678", NombreSistemaInformatico: "MyApp", IdSistemaInformatico: "A1", Version: "1.0", NumeroInstalacion: "00001", } client, err := verifactu.New(software, verifactu.WithCertificate(cert), verifactu.WithSigning(), // Auto-sign all documents verifactu.InProduction(), ) if err != nil { panic(err) } // Load invoice env := new(gobl.Envelope) data, _ := os.ReadFile("invoice.json") json.Unmarshal(data, env) // Register (auto-signed) reg, err := client.RegisterInvoice(env, nil) if err != nil { panic(err) } if reg.Signature == nil { panic("signature missing!") } // Prepare request req, _ := client.NewInvoiceRequest(inv.Supplier) req.AddRegistration(reg) // Send to AEAT ctx := context.Background() resp, err := client.SendInvoiceRequest(ctx, req) if err != nil { panic(err) } // Check result for _, line := range resp.Lines { if err := line.Error(); err == nil { println("✓ Invoice accepted") } } } ``` -------------------------------- ### Example Previous Invoice Info JSON Source: https://github.com/invopop/gobl.verifactu/blob/main/README.md An example structure for the previous invoice information file required by the `send` command. This includes details like the issuer's NIF, series, date, and fingerprint. ```json { "emisor": "B12345678", "serie": "SAMPLE-001", "fecha": "2024-11-28", "huella": "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF" } ``` -------------------------------- ### Register Event Summary Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/13-noverifactu-events.md Example for registering a general event summary, providing a concise overview of detected events. ```go status := &bill.Status{ UUID: uuid.New().String(), Issued: time.Now(), Lines: []*bill.StatusLine{ { Key: noverifactu.KeyEventSummary, Description: "Monthly summary: 150 startups, 150 shutdowns, 5 anomalies detected", }, }, } eventReg, _ := client.RegisterEvent(&gobl.Envelope{Document: status}, nil) ``` -------------------------------- ### Register Invoice with Override Installation Number Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/07-software-configuration.md Demonstrates how to override the default installation number when registering an invoice. This is useful for multi-installation scenarios. ```go // Installation 1: Default from client config reg1, _ := client.RegisterInvoice(env1, nil) // Installation 2: Override installation number reg2, _ := client.RegisterInvoice( env2, nil, verifactu.WithInstallationNumber("00002"), ) // Installation 3: Override both installation number and other parameters reg3, _ := client.RegisterInvoice( env3, nil, verifactu.WithInstallationNumber("00003"), ) ``` -------------------------------- ### ISO 8601 Timestamp Example Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/06-chain-data.md Provides an example of an ISO 8601 formatted timestamp with offset, as used for generation timestamps in Verifactu. ```text 2024-06-15T14:30:45-02:00 ``` -------------------------------- ### Example of Formatting Error Message Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/08-errors.md Demonstrates how to create and print a formatted error message using the `WithMessage` method and the `Error()` method. ```go err := verifactu.ErrValidation.WithMessage("missing tax ID") fmt.Println(err.Error()) // Output: "validation: missing tax ID" ``` -------------------------------- ### Register Anomaly Detection Launch Event Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/13-noverifactu-events.md Example for registering an anomaly detection launch event, specifying the date range for the check. ```go status := &bill.Status{ UUID: uuid.New().String(), Issued: time.Now(), Provider: "software-name", Lines: []*bill.StatusLine{ { Key: noverifactu.KeyInvoiceAnomalyLaunch, Description: "Started integrity check on invoices from 2024-06-01 to 2024-06-30", }, }, } eventReg, _ := client.RegisterEvent(&gobl.Envelope{Document: status}, nil) ``` -------------------------------- ### Override Software Installation Number Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/01-client.md Overrides the software installation number for a specific document. Accepts the installation code as a string. ```go func WithInstallationNumber(code string) GenerateOption ``` -------------------------------- ### Register Invoice with Software Info Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/07-software-configuration.md Includes software information in registration documents. The `SistemaInformatico` field contains the `Software` struct with details like name, ID, and installation number. ```go reg, err := client.RegisterInvoice(env, prev) // reg.SistemaInformatico contains the Software struct // reg.SistemaInformatico.NombreRazon == "Invopop S.L." // reg.SistemaInformatico.IdSistemaInformatico == "A1" // reg.SistemaInformatico.NumeroInstalacion == "00001" (unless overridden) ``` -------------------------------- ### No Identification (Returns nil) Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/11-party-identification.md This example shows a scenario where no identification is provided (nil TaxID and Identities). The newParty function will return nil in this case. ```go customer := &org.Party{ Name: "Anonymous", TaxID: nil, Identities: nil, } pty := newParty(customer, invoice.IssueDate) ``` -------------------------------- ### Use GOBL VeriFactu Package to Send Invoices Source: https://github.com/invopop/gobl.verifactu/blob/main/README.md This example demonstrates how to use the GOBL VeriFactu package to convert a GOBL invoice, register it, and send it to the AEAT. Ensure the supplier in the invoice has a 'Tax ID' with country 'ES'. You will need to provide a software definition, load a certificate, and handle previous chain data from your local database. ```go package main import ( "context" "encoding/json" "fmt" "os" "github.com/invopop/gobl" verifactu "github.com/invopop/gobl.verifactu" "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 S.L.", // 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.InTesting(), // Use the testing environment } vc, err := verifactu.New(software, opts...) if err != nil { panic(err) } // Prepare previous chain data. Ideally you want to do this from // your own database. prevData, err := os.ReadFile("./path/to/previous_invoice.json") if err != nil { panic(err) } prev := new(verifactu.ChainData) if err := json.Unmarshal([]byte(prevData), prev); err != nil { panic(err) } // Generate a registration document and update the envelope. reg, err := vc.RegisterInvoice(env) if err != nil { panic(err) } inv := env.(*bill.Invoice) ir, err := vc.InvoiceRequest(inv.Supplier) if err != nil { panic(err) } inv.AddRegistration(reg) // Send the document to the tax agency out, err = vc.SendInvoiceRequest(ctx, ir) if err != nil { panic(err) } line := out.Lines[0] // 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(line.ChainData()) if err != nil { panic(err) } fmt.Printf("Generated document with fingerprint: \n%s\n", string(cd)) } ``` -------------------------------- ### EU Customer with VAT Identification Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/11-party-identification.md This example is for EU customers requiring VAT identification. The TaxID includes the EU country code and VAT number. ```go customer := &org.Party{ Name: "SARL Example", TaxID: &org.TaxID{ Country: l10n.FR, Code: cbc.Code("12345678901"), }, } pty := newParty(customer, invoice.IssueDate) ``` -------------------------------- ### Define EventSoftware Structure in Go Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/05-event-registration.md Defines the structure for software system details associated with an event. Includes fields for software name, ID, version, and installation number, along with optional fields for company details and usage types. ```go type EventSoftware struct { Name string `xml:"sf:NombreRazon"` NIF string `xml:"sf:NIF,omitempty"` IDOther *EventOtherID `xml:"sf:IDOtro,omitempty"` SoftwareName string `xml:"sf:NombreSistemaInformatico,omitempty"` SoftwareID string `xml:"sf:IdSistemaInformatico"` Version string `xml:"sf:Version"` InstallationNumber string `xml:"sf:NumeroInstalacion"` OnlyVerifactu string `xml:"sf:TipoUsoPosibleSoloVerifactu,omitempty"` MultiOT string `xml:"sf:TipoUsoPosibleMultiOT,omitempty"` MultipleOT string `xml:"sf:IndicadorMultiplesOT,omitempty"` } ``` -------------------------------- ### Software Configuration Type Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/14-types-reference.md Details the metadata for software used in the system, including vendor name, tax ID, application name and ID, version, installation number, and optional multi-office flags. ```plaintext Software (software metadata) ├─ NombreRazon (vendor name) ├─ NIF (vendor tax ID) ├─ NombreSistemaInformatico (app name) ├─ IdSistemaInformatico (app ID) ├─ Version ├─ NumeroInstalacion └─ Optional multi-office flags ``` -------------------------------- ### Example of Using errors.Is with Custom Errors Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/08-errors.md Shows how to use the `errors.Is` function to check if an error matches a specific custom error category, like `verifactu.ErrValidation`. ```go if errors.Is(err, verifactu.ErrValidation) { fmt.Println("Validation error") } ``` -------------------------------- ### Implement Retry Logic for API Requests Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/15-quick-start.md Handle transient connection errors by implementing a retry mechanism. This example retries a request up to three times, waiting 5 seconds between attempts for connection errors. ```go for attempt := 0; attempt < 3; attempt++ { resp, err := client.SendInvoiceRequest(ctx, req) if err == nil { return resp } if errors.Is(err, verifactu.ErrConnection) { time.Sleep(5 * time.Second) continue } return nil, err } ``` -------------------------------- ### Override Installation Number During Document Generation Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/07-software-configuration.md Dynamically change the installation number for a specific document generation using the `WithInstallationNumber()` option. This is useful when supporting multiple installations within a single client application. ```go reg, err := client.RegisterInvoice( env, prev, verifactu.WithInstallationNumber("00002"), ) ``` -------------------------------- ### Create Verifactu Client Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/15-quick-start.md Initializes the Verifactu client for document generation and submission. Use the sandbox environment for testing purposes. ```go client, err := verifactu.New(software, verifactu.WithCertificate(cert), verifactu.InSandbox(), // or verifactu.InProduction() ) ``` -------------------------------- ### Initialize Verifactu Client in Sandbox Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/15-quick-start.md Use this snippet to create a Verifactu client instance configured for the sandbox environment. It defaults to sandbox mode. Ensure you have the necessary software details and test certificates. ```go client, _ := verifactu.New(software, verifactu.WithCertificate(testCert), verifactu.InSandbox(), // Default ) ``` -------------------------------- ### Initialize Verifactu Client in Production Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/15-quick-start.md Configure the Verifactu client for production deployment. This requires a valid AEAT-trusted certificate and registered software details. Proper chain management is also essential. ```go client, _ := verifactu.New(software, verifactu.WithCertificate(prodCert), verifactu.InProduction(), ) ``` -------------------------------- ### Enable Automatic Signing Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/12-document-signing.md Use `verifactu.WithSigning()` during client initialization to automatically sign all generated documents. Ensure a certificate is provided. ```go client, err := verifactu.New(software, verifactu.WithCertificate(cert), verifactu.WithSigning(), ) ``` -------------------------------- ### Create Software Configuration in Go Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/07-software-configuration.md Instantiate a software configuration object directly in Go. This is typically done once and reused for all document operations. ```go software := &verifactu.Software{ NombreRazon: "Invopop S.L.", NIF: "B85905495", NombreSistemaInformatico: "gobl.verifactu", IdSistemaInformatico: "A1", Version: "1.0", NumeroInstalacion: "00001", } client, err := verifactu.New(software, verifactu.WithCertificate(cert)) ``` -------------------------------- ### Register Anomaly Detection Result Event Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/13-noverifactu-events.md Example of registering an anomaly detection result event, detailing the specific anomaly found in an invoice. ```go status := &bill.Status{ UUID: uuid.New().String(), Issued: time.Now(), Lines: []*bill.StatusLine{ { Key: noverifactu.KeyInvoiceAnomaly, Description: "Anomaly in invoice INV-001: Missing recipient", }, }, } eventReg, _ := client.RegisterEvent(&gobl.Envelope{Document: status}, nil) ``` -------------------------------- ### Use Sandbox Environment Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/01-client.md Configures the client to use the testing or sandbox environment. ```go func InSandbox() Option ``` -------------------------------- ### Sign Events with Client Certificate Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/05-event-registration.md Initialize a new `verifactu` client configured to sign events using the provided software and client certificate. Ensure `verifactu.WithSigning()` is used to enable signing. ```go client, err := verifactu.New(software, verifactu.WithCertificate(cert), verifactu.WithSigning(), ) ``` -------------------------------- ### Not Subject Operation Desglose Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/10-breakdown-taxes.md Example of a Desglose entry for an operation that is not subject to tax. The CalificacionOperacion is set to 'N1', and certain tax-related fields are omitted. ```yaml Desglose: - Impuesto: "01" CalificacionOperacion: "N1" (Not subject) BaseImponibleOImporteNoSujeto: "1000.00" (No ClaveRegimen, no TipoImpositivo) ``` -------------------------------- ### Run All Tests Source: https://github.com/invopop/gobl.verifactu/blob/main/README.md Execute the library's test suite to validate the conversion and submission process. Ensure you have the necessary Go environment set up. ```bash go test ./... ``` -------------------------------- ### Enabling Automatic Signing in Verifactu Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/15-quick-start.md Shows how to configure the Verifactu client to automatically sign all documents by providing the WithSigning() option during client initialization. This simplifies the signing process for registrations and cancellations. ```go // Enable automatic signing client, err := verifactu.New(software, verifactu.WithCertificate(cert), verifactu.WithSigning(), // Auto-sign all documents ) // Now all registrations/cancellations are signed automatically reg, _ := client.RegisterInvoice(env, prev) if reg.Signature != nil { fmt.Println("Document is signed") } ``` -------------------------------- ### Get Current Time Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/01-client.md Retrieves the current time for VeriFactu document generation. It returns a custom time if set, otherwise the system time. ```go func (c *Client) CurrentTime() time.Time ``` ```go ts := client.CurrentTime() fmt.Println(ts) ``` -------------------------------- ### Chaining Invoices with Verifactu Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/15-quick-start.md Demonstrates how to chain invoices by loading the previous chain data and saving the new chain data after registration. This is useful for sequences of related invoices. ```go // Load previous chain from database (nil for first) var prevChain *verifactu.ChainData if previousInvoiceExists { prevData, _ := db.GetChainData(previousID) json.Unmarshal(prevData, &prevChain) } // Register with chain reg, _ := client.RegisterInvoice(env, prevChain) // After successful submission, save for next newChain := reg.ChainData() chainJSON, _ := json.Marshal(newChain) db.SaveChainData(invoiceID, chainJSON) ``` -------------------------------- ### Configure Software Details Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/15-quick-start.md Sets up software identification details required by the tax authority. These details appear on all generated documents. ```go software := &verifactu.Software{ NombreRazon: "Your Company Name", NIF: "B12345678", // Your company's tax ID NombreSistemaInformatico: "MyInvoicingApp", IdSistemaInformatico: "A1", // Must match registered ID Version: "1.0", NumeroInstalacion: "00001", // Installation number } ``` -------------------------------- ### Use Production Environment Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/01-client.md Configures the client to use the production AEAT environment. The default is the sandbox environment. ```go func InProduction() Option ``` -------------------------------- ### New Client Constructor Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/01-client.md Creates a new VeriFactu client instance. It requires software configuration details and accepts optional configuration functions. ```APIDOC ## New Client Constructor ### Description Creates a new VeriFactu client with shared software configuration and options. ### Function Signature ```go func New(software Software, opts ...Option) (*Client, error) ``` ### Parameters #### Path Parameters - **software** (Software) - Required - Software definition details including name, NIF, version, and installation number - **opts** ([]Option) - Optional - Variable-length option functions to configure the client behavior ### Returns - `(*Client, error)` - A configured client instance or error if initialization fails. ### Example ```go software := &verifactu.Software{ NombreRazon: "Company S.L.", NIF: "B123456789", NombreSistemaInformatico: "Software Name", IdSistemaInformatico: "A1", Version: "1.0", NumeroInstalacion: "00001", } cert, err := xmldsig.LoadCertificate("./cert.p12", "password") if err != nil { panic(err) } opts := []verifactu.Option{ verifactu.WithCertificate(cert), verifactu.InSandbox(), } client, err := verifactu.New(software, opts...) if err != nil { panic(err) } ``` ``` -------------------------------- ### Reverse Charge Operation Desglose Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/10-breakdown-taxes.md Example of a Desglose entry for a reverse charge operation. The tax is not repercuted by the supplier but is paid by the recipient, hence CuotaRepercutida is 0. ```yaml Desglose: - Impuesto: "01" ClaveRegimen: "01" CalificacionOperacion: "S2" (Reverse charge) TipoImpositivo: "0" (Recipient pays tax) BaseImponibleOImporteNoSujeto: "1000.00" CuotaRepercutida: "0.00" ``` -------------------------------- ### Configure Verifactu via Environment Variables Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/15-quick-start.md Set environment variables or use a .env file to configure the CLI tool. For library usage, pass configuration directly to the New() function. ```bash CERTIFICATE_PATH=./cert.p12 CERTIFICATE_PASSWORD=mypassword DEBUG=true ``` -------------------------------- ### Bytes Method for InvoiceResponse Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/04-invoice-request-response.md Prepares an indented XML document from the InvoiceResponse. Use this to get XML bytes for persistence or further processing. Returns XML bytes or an error. ```go func (ir *InvoiceResponse) Bytes() ([]byte, error) ``` ```go data, err := resp.Bytes() if err != nil { panic(err) } ``` -------------------------------- ### VeriFactu Client Constructor Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/01-client.md Function signature for creating a new VeriFactu client. It requires software details and accepts optional configuration functions. ```go func New(software Software, opts ...Option) (*Client, error) ``` -------------------------------- ### Surcharge Equivalent (VAT) Desglose Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/10-breakdown-taxes.md Example of a Desglose entry that includes the surcharge equivalent for VAT. This applies in specific regimes and adds extra fields for the surcharge calculation. ```yaml Desglose: - Impuesto: "01" ClaveRegimen: "01" CalificacionOperacion: "S1" TipoImpositivo: "21" BaseImponibleOImporteNoSujeto: "1000.00" CuotaRepercutida: "210.00" TipoRecargoEquivalencia: "5.2" CuotaRecargoEquivalencia: "52.00" ``` -------------------------------- ### Sign Documents using SignDocument or Client.WithSigning Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/INDEX.md Use `SignDocument()` or `Client.WithSigning()` as outlined in `12-document-signing.md` for signing documents. This involves handling certificates and XAdES configuration. ```go SignDocument() ``` ```go Client.WithSigning() ``` -------------------------------- ### Define Software for Multi-Office Scenarios Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/07-software-configuration.md Defines a `Software` struct for scenarios supporting multiple offices. Set `TipoUsoPosibleMultiOT` and `IndicadorMultiplesOT` to 'S' to indicate multi-office support and active usage. ```go software := &verifactu.Software{ NombreRazon: "Invopop S.L.", NIF: "B85905495", NombreSistemaInformatico: "gobl.verifactu", IdSistemaInformatico: "A1", Version: "1.0", NumeroInstalacion: "00001", TipoUsoPosibleMultiOT: "S", // Supports multiple offices IndicadorMultiplesOT: "S", // Multiple offices are active } ``` -------------------------------- ### Set Verifactu to Production Environment Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/README.md Use this function to configure the Verifactu client for the production environment. This requires registered software and valid certificates for live invoice processing. ```go verifactu.InProduction() ``` -------------------------------- ### Simple VAT Invoice (General Regime, 21% Rate) Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/10-breakdown-taxes.md Example of a Desglose entry for a standard VAT invoice under the general regime with a 21% tax rate. This is a common scenario for taxed operations. ```yaml Desglose: - Impuesto: "01" (VAT) ClaveRegimen: "01" (General) CalificacionOperacion: "S1" (Taxed, no reverse charge) TipoImpositivo: "21" BaseImponibleOImporteNoSujeto: "1000.00" CuotaRepercutida: "210.00" ``` -------------------------------- ### Get Compact XML Bytes for Signed Document Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/12-document-signing.md Retrieve the signed document as compact (unindented) XML bytes using the Bytes() method. This format is essential for preserving the signature's integrity. ```go data, err := reg.Bytes() // Compact XML // data is suitable for transmission and archival ``` -------------------------------- ### Set Verifactu to Sandbox Environment Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/README.md Use this function to configure the Verifactu client for the sandbox environment. This is the default setting and is suitable for development and testing purposes. ```go verifactu.InSandbox() // Default ``` -------------------------------- ### Batch Invoice Registration and Submission Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/15-quick-start.md Process multiple invoices in a batch. This pattern involves loading each invoice's envelope, registering it to get chain data, adding it to a request, and finally sending the request. ```go for _, invoice := range invoices { env := loadGOBLEnvelope(invoice) reg, _ := client.RegisterInvoice(env, getChainData(invoice.Previous)) req.AddRegistration(reg) } resp, _ := client.SendInvoiceRequest(ctx, req) ``` -------------------------------- ### Chain Events Using EventChainData Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/13-noverifactu-events.md Demonstrates how to chain events by creating an EventChainData object from the first registered event and passing it as the 'prev' parameter for subsequent event registrations. This is crucial for maintaining an audit trail. ```go // First event firstEvent, _ := client.RegisterEvent(env1, nil) firstChain := &verifactu.EventChainData{ EventType: "01", GenerationTimestamp: firstEvent.Event.GenerationTimestamp, Fingerprint: firstEvent.Event.Fingerprint, } // Save firstChain to database... // Second event (chained to first) secondEvent, _ := client.RegisterEvent(env2, firstChain) ``` -------------------------------- ### Load Software Configuration via .env File Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/07-software-configuration.md Configure software settings by defining them in a .env file. This is a common practice for managing environment-specific configurations. ```dotenv 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 ``` -------------------------------- ### Check Sandbox Environment Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/01-client.md Determines if the client is configured to use the sandbox environment. Returns true for sandbox, false for production. ```go func (c *Client) Sandbox() bool ``` ```go if client.Sandbox() { fmt.Println("Using sandbox environment") } ``` -------------------------------- ### Register Event using Client.RegisterEvent Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/INDEX.md Implement `Client.RegisterEvent()` from `01-client.md` for registering system events that are not part of the Verifactu system, as detailed in `05-event-registration.md` and `13-noverifactu-events.md`. ```go Client.RegisterEvent() ``` -------------------------------- ### Register Invoice with Client Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/02-invoice-registration.md Use `Client.RegisterInvoice()` to create a new invoice registration. Handle potential errors during the registration process. ```go reg, err := client.RegisterInvoice(env, previousChainData) if err != nil { return err } ``` -------------------------------- ### Load Software Configuration via Environment Variables (CLI) Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/07-software-configuration.md Configure software settings by exporting environment variables. This method is useful for command-line interface (CLI) usage. ```bash export SOFTWARE_COMPANY_NIF=B85905495 export SOFTWARE_COMPANY_NAME="Invopop S.L." export SOFTWARE_NAME="gobl.verifactu" export SOFTWARE_VERSION="1.0" export SOFTWARE_ID_SISTEMA_INFORMATICO="A1" export SOFTWARE_NUMERO_INSTALACION="00001" ``` -------------------------------- ### Implement Party Structure for Foreign Customers Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/INDEX.md Implement the `Party` structure as described in `11-party-identification.md` to manage foreign customer identification, including NIF vs. IDOtro and EU VAT considerations. ```go Party ``` -------------------------------- ### Certificate Loading Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/12-document-signing.md Demonstrates how to load a signing certificate from a PKCS#12 (.p12) file using the xmldsig library. ```APIDOC ## LoadCertificate ### Description Loads a signing certificate from a PKCS#12 (.p12) file. ### Function Signature ```go func LoadCertificate(path, password string) (*xmldsig.Certificate, error) ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **path** (string) - Required - Path to the .p12 certificate file - **password** (string) - Required - Password for the .p12 certificate file ### Request Example ```go cert, err := xmldsig.LoadCertificate(path, password) if err != nil { return err } ``` ### Response #### Success Response (*xmldsig.Certificate) Returns the loaded certificate object containing the private key, public certificate chain, and subject information. #### Error Response (error) Returns an error if the certificate file cannot be loaded or accessed. ``` -------------------------------- ### Load Certificate for TLS Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/09-xml-envelope.md Loads a client certificate from a .p12 file using a password, required for TLS configuration with the Verifactu client. ```go import ( "github.com/invopop/gobl/client" "github.com/invopop/gobl/regtech/verifactu" "github.com/invopop/gobl/xades" ) // Assuming 'software' is a valid software identifier. func setupClientWithCert(software string) (*verifactu.Client, error) { cert, err := xades.LoadCertificate("path/to/cert.p12", "password") if err != nil { return nil, err } client, err := verifactu.New(software, verifactu.WithCertificate(cert)) if err != nil { return nil, err } return client, nil } ``` -------------------------------- ### VeriFactu Signing Options Configuration Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/12-document-signing.md Configure xmldsig options for VeriFactu compliance, including XMLDSig and XAdES settings, and the signing certificate. These options ensure enveloped signatures and XAdES compliance. ```go signOpts := []xmldsig.Option{ xmldsig.WithXMLDSigConfig(verifactu.XMLDSigConfig()), xmldsig.WithXAdESConfig(verifactu.XAdESConfig()), xmldsig.WithCertificate(cert), } ``` -------------------------------- ### Enable Document Signing Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/01-client.md Enables signing for all generated documents and allows passing additional `xmldsig.Option` for controlling document ID and signing time. ```go func WithSigning(opts ...xmldsig.Option) Option ``` -------------------------------- ### Create and Send Invoice Request Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/04-invoice-request-response.md This snippet demonstrates the process of creating a new invoice request, adding necessary registrations, and sending it to the AEAT. It includes error handling and context management for the request. Ensure you have a configured client and necessary supplier information. ```go ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defunc cancel() { // ... } // Create request req, err := client.NewInvoiceRequest(supplier) if err != nil { panic(err) } // Add registrations reg, _ := client.RegisterInvoice(env1, prev1) req.AddRegistration(reg) // Send to AEAT resp, err := client.SendInvoiceRequest(ctx, req) if err != nil { panic(err) } // Check results fmt.Printf("Overall status: %s\n", resp.Status) for i, line := range resp.Lines { fmt.Printf("Line %d: %s\n", i, line.Message()) if err := line.Error(); err != nil { fmt.Printf(" Error: %v\n", err) } // Extract chain data for next invoice chainData := req.Lines[i].ChainData() if chainData != nil { // Store in database for next document } } ``` -------------------------------- ### Error Handling in Verifactu Operations Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/12-document-signing.md This snippet shows how to handle errors when loading certificates, creating the Verifactu client, and registering an invoice. It checks for nil signatures when signing is required. ```go cert, err := xmldsig.LoadCertificate("./cert.p12", "password") if err != nil { return fmt.Errorf("loading certificate: %w", err) } client, err := verifactu.New(software, verifactu.WithCertificate(cert)) if err != nil { return fmt.Errorf("creating client: %w", err) } reg, err := client.RegisterInvoice(env, prev) if err != nil { return fmt.Errorf("registration failed: %w", err) } if reg.Signature == nil && needsSigning { return errors.New("document not signed") } ``` -------------------------------- ### Initialize NO VERI*FACTU Rules Set Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/13-noverifactu-events.md The `Rules` variable provides a pre-configured set of validation rules for `bill.Status` documents specific to the NO VERI*FACTU modality. It combines status-specific rules with complement rules. ```go var Rules = rules.NewSet("NOVERIFACTU", append(statusRules, complementRules...)...) ``` -------------------------------- ### Load Certificate Safely Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/08-errors.md Always check for errors when loading a certificate to ensure it is accessible and valid. ```go cert, err := xmldsig.LoadCertificate(path, password) if err != nil { return fmt.Errorf("loading certificate: %w", err) } ``` -------------------------------- ### Set Signing Certificate Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/01-client.md Use this option to set the signing certificate for document signing. Requires a `xmldsig.Certificate` object. ```go func WithCertificate(cert *xmldsig.Certificate) Option ``` -------------------------------- ### Configuration Options Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/01-client.md Options that configure the client's behavior. ```APIDOC ## WithCertificate Sets the signing certificate for document signing. ```go func WithCertificate(cert *xmldsig.Certificate) Option ``` ``` ```APIDOC ## WithCurrentTime Sets a custom current time for testing purposes. ```go func WithCurrentTime(curTime time.Time) Option ``` ``` ```APIDOC ## WithRepresentative Sets a legal representative for the obligated party, used when the supplier's certificate is unavailable. ```go func WithRepresentative(name, nif string) Option ``` ``` ```APIDOC ## InProduction Configures the client to use the production AEAT environment. Default is sandbox. ```go func InProduction() Option ``` ``` ```APIDOC ## InSandbox Configures the client to use the testing/sandbox environment. ```go func InSandbox() Option ``` ``` ```APIDOC ## WithCorporateSeal Configures the client to use corporate seal endpoints (Sello de Entidad) instead of regular certificates. ```go var WithCorporateSeal Option ``` ``` ```APIDOC ## WithSigning Enables signing for all generated documents and passes additional xmldsig options for controlling document ID and signing time. ```go func WithSigning(opts ...xmldsig.Option) Option ``` ``` -------------------------------- ### Event Type Codes Reference Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/14-types-reference.md Lists codes for various system events, including startup, shutdown, anomaly detection, and data export. ```text 01 — System startup 02 — System shutdown 03 — Anomaly detection launch (invoices) 04 — Anomaly detected (invoices) 05 — Anomaly detection launch (events) 06 — Anomaly detected (events) 07 — Backup/restoration 08 — Invoice export 09 — Event export 10 — Event summary 90 — Other ``` -------------------------------- ### WithCode Method Implementation Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/08-errors.md Creates a new error instance by copying an existing error and setting a specific code from the remote service. ```go func (e *Error) WithCode(code string) *Error ``` -------------------------------- ### Client Methods Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/INDEX.md The Client type is the entry point for all operations. It provides methods for creating registrations, cancellations, and submitting invoice requests. ```APIDOC ## Client Methods ### Description Provides methods for invoice registration, cancellation, and submission to AEAT. ### Methods - **Client.New()**: Constructor for the Client. - **Client.RegisterInvoice()**: Creates an invoice registration. - **Client.CancelInvoice()**: Creates an invoice cancellation. - **Client.SendInvoiceRequest()**: Submits an invoice request to AEAT. ``` -------------------------------- ### Register First Document in Chain Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/06-chain-data.md For the initial document in a chain (invoice, cancellation, or event), pass `nil` as the chain data to the `RegisterInvoice` function. The response will indicate if it's the first record. ```go reg, err := client.RegisterInvoice(env, nil) if err != nil { return err } // The registration's Encadenamiento will have PrimerRegistro = "S" if reg.Encadenamiento.PrimerRegistro == "S" { fmt.Println("First document in chain") } ``` -------------------------------- ### Send Invoice Request to VeriFactu Gateway Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/01-client.md Sends a prepared invoice request to the VeriFactu gateway. Use this method for submitting invoices for processing. It requires a context for cancellation and timeouts, and an InvoiceRequest object. ```go func (c *Client) SendInvoiceRequest(ctx context.Context, ir *InvoiceRequest) (*InvoiceResponse, error) ``` ```go ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) def cancel() resp, err := client.SendInvoiceRequest(ctx, req) if err != nil { panic(err) } for _, line := range resp.Lines { if err := line.Error(); err != nil { fmt.Println("Line error:", err) } } ``` -------------------------------- ### Chaining Subsequent Events Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/05-event-registration.md Register a new event by referencing the previous event's fingerprint. Ensure you have loaded the previous event's chain data. ```go // Get previous event's chain data prevEventChain := new(verifactu.EventChainData) // ... load from database ... // Register next event with chaining nextEvent, err := client.RegisterEvent(env, prevEventChain) if err != nil { panic(err) } ``` -------------------------------- ### VeriFactu Client Type Definition Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/01-client.md Defines the structure of the VeriFactu client, which holds configuration for software, environment, certificates, and connection details. ```go type Client struct { software Software env Environment rep *Issuer curTime time.Time cert *xmldsig.Certificate conn *connection withSeal bool signing bool signOpts []xmldsig.Option } ``` -------------------------------- ### Sign XML Document with VeriFactu Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/12-document-signing.md Signs any XML-marshalable struct using the VeriFactu XAdES configuration. Requires a document object, a signing certificate, and optionally additional xmldsig options. ```go cert, err := xmldsig.LoadCertificate("./cert.p12", "password") if err != nil { panic(err) } reg, _ := client.RegisterInvoice(env, prev) sig, err := verifactu.SignDocument(reg, cert) if err != nil { panic(err) } // Attach signature to document reg.Signature = sig ``` -------------------------------- ### Complete Invoice Request Flow Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/09-xml-envelope.md Demonstrates the full process of creating an invoice request, adding registrations, enveloping it, serializing to XML, sending it, and processing the response. ```go import ( "context" "fmt" "github.com/invopop/gobl/client" "github.com/invopop/gobl/regtech/verifactu" "github.com/invopop/gobl/xades" ) // Assuming 'client' is an initialized verifactu.Client, and 'supplier' is a valid supplier object. // 'env1', 'prev1', 'env2', 'prev2' are assumed to be valid registration environments and previous states. func exampleFlow(client *verifactu.Client, supplier *client.Supplier, env1, prev1, env2, prev2 interface{}) error { // 1. Create invoice request req, err := client.NewInvoiceRequest(supplier) if err != nil { return err } // 2. Add registrations reg, _ := client.RegisterInvoice(env1, prev1) req.AddRegistration(reg) reg2, _ := client.RegisterInvoice(env2, prev2) req.AddRegistration(reg2) // 3. Wrap in SOAP envelope envelope := req.Envelop() // 4. Serialize to XML data, err := envelope.Bytes() if err != nil { return err } // 5. Send via client (which handles the HTTP POST) ctx := context.Background() resp, err := client.SendInvoiceRequest(ctx, req) if err != nil { return err } // 6. Process response for _, line := range resp.Lines { fmt.Println(line.Message()) } return nil } ``` -------------------------------- ### Option Type Interface for Client Configuration Source: https://github.com/invopop/gobl.verifactu/blob/main/_autodocs/14-types-reference.md Defines a function type for configuring the Client. Used for options like setting certificates, time, or representative details. ```go type Option func(*Client) ```