Skip to main content

Overview

CUFD (Código Único de Facturación Diaria) is a daily invoicing code required for issuing invoices. This code has a 24-hour validity period and must be obtained daily for each point of sale. A valid CUIS code is required before requesting a CUFD.

Single CUFD Request

Request a CUFD code for a specific point of sale.

Method Signature

func (s *SiatCodigosService) SolicitudCufd(
    ctx context.Context,
    config config.Config,
    request models.CufdRequest,
) (*soap.EnvelopeResponse[codigos.CufdResponse], error)

Building the Request

Use the builder pattern to construct a CUFD request:
request := models.Codigos.NewCufdRequest().
    WithCodigoAmbiente(1).
    WithCodigoModalidad(1).
    WithCodigoSistema("SystemCode123").
    WithCodigoSucursal(0).
    WithCodigoPuntoVenta(0).
    WithCuis("CUIS-CODE-HERE").
    WithNit(1234567890).
    Build()

Request Parameters

codigoAmbiente
int
required
Environment code:
  • 1 - Production
  • 2 - Testing/Development
codigoModalidad
int
required
Operation modality code
codigoSistema
string
required
System identification code assigned by SIAT
codigoSucursal
int
required
Branch office code
codigoPuntoVenta
int
required
Point of sale code. Can be 0 for branch-level CUFD
cuis
string
required
Valid CUIS code for this branch/point of sale
nit
int64
required
Company’s tax identification number (NIT)

Response Structure

type CufdResponse struct {
    RespuestaCufd RespuestaCufd
}

type RespuestaCufd struct {
    Codigo        string
    CodigoControl string
    Direccion     string
    FechaVigencia time.Time
    MensajesList  []MensajeServicio
    Transaccion   bool
}

Response Fields

codigo
string
The generated CUFD code to be used in invoice generation
codigoControl
string
Control code associated with the CUFD
direccion
string
Physical address associated with the branch/point of sale
fechaVigencia
time.Time
Expiration date and time of the CUFD (valid for 24 hours)
transaccion
bool
Indicates if the request was successful
mensajesList
[]MensajeServicio
List of messages or errors from the service

Example Usage

package main

import (
    "context"
    "fmt"
    "log"
    
    "github.com/ron86i/go-siat/pkg/client"
    "github.com/ron86i/go-siat/pkg/config"
    "github.com/ron86i/go-siat/pkg/models"
)

func main() {
    // Initialize client
    cfg := config.Config{
        Token:      "your-api-token",
        BaseURL:    "https://pilotosiatservicios.impuestos.gob.bo",
        Ambiente:   1,
        Modalidad:  1,
        Sistema:    "SystemCode123",
        NIT:        1234567890,
    }
    
    siatClient, err := client.NewSiatClient(cfg)
    if err != nil {
        log.Fatal(err)
    }
    
    // Build request (requires a valid CUIS)
    request := models.Codigos.NewCufdRequest().
        WithCodigoAmbiente(cfg.Ambiente).
        WithCodigoModalidad(cfg.Modalidad).
        WithCodigoSistema(cfg.Sistema).
        WithCodigoSucursal(0).
        WithCodigoPuntoVenta(0).
        WithCuis("YOUR-VALID-CUIS-CODE").
        WithNit(cfg.NIT).
        Build()
    
    // Execute request
    ctx := context.Background()
    resp, err := siatClient.Codigos.SolicitudCufd(ctx, request)
    if err != nil {
        log.Fatalf("Failed to request CUFD: %v", err)
    }
    
    // Check transaction status
    if !resp.Body.Response.RespuestaCufd.Transaccion {
        fmt.Println("CUFD request failed:")
        for _, msg := range resp.Body.Response.RespuestaCufd.MensajesList {
            fmt.Printf("  Error %d: %s\n", msg.Codigo, msg.Descripcion)
        }
        return
    }
    
    // Success
    fmt.Printf("CUFD Code: %s\n", resp.Body.Response.RespuestaCufd.Codigo)
    fmt.Printf("Control Code: %s\n", resp.Body.Response.RespuestaCufd.CodigoControl)
    fmt.Printf("Address: %s\n", resp.Body.Response.RespuestaCufd.Direccion)
    fmt.Printf("Valid until: %s\n", resp.Body.Response.RespuestaCufd.FechaVigencia)
}

Bulk CUFD Request

Request multiple CUFD codes in a single operation for different branches and points of sale.

Method Signature

func (s *SiatCodigosService) SolicitudCufdMasivo(
    ctx context.Context,
    config config.Config,
    request models.CufdMasivoRequest,
) (*soap.EnvelopeResponse[codigos.CufdMasivoResponse], error)

Building the Request

// Define the list of branches and points of sale with their CUIS codes
puntoVenta1 := 0
puntoVenta2 := 1

datosSolicitud := []codigos.SolicitudListaCufdDto{
    {
        CodigoSucursal:   0,
        CodigoPuntoVenta: &puntoVenta1,
        Cuis:             "CUIS-CODE-FOR-BRANCH-0-POS-0",
    },
    {
        CodigoSucursal:   0,
        CodigoPuntoVenta: &puntoVenta2,
        Cuis:             "CUIS-CODE-FOR-BRANCH-0-POS-1",
    },
}

request := models.Codigos.NewCufdMasivoRequest().
    WithCodigoAmbiente(1).
    WithCodigoModalidad(1).
    WithCodigoSistema("SystemCode123").
    WithNit(1234567890).
    WithDatosSolicitud(datosSolicitud).
    Build()

Request Parameters

codigoAmbiente
int
required
Environment code (1 for production, 2 for testing)
codigoModalidad
int
required
Operation modality code
codigoSistema
string
required
System identification code
nit
int64
required
Company’s tax identification number
datosSolicitud
[]SolicitudListaCufdDto
required
List of branch, point of sale, and CUIS combinations

SolicitudListaCufdDto Structure

codigoSucursal
int
required
Branch office code
codigoPuntoVenta
*int
required
Pointer to point of sale code
cuis
string
required
Valid CUIS code for this branch/point of sale combination

Response Structure

type CufdMasivoResponse struct {
    RespuestaCufdMasivo RespuestaCufdMasivo
}

type RespuestaCufdMasivo struct {
    ListaRespuestasCufd []RespuestaListaRegistroCufdSoapDto
    MensajesList        []MensajeServicio
    Transaccion         bool
}

type RespuestaListaRegistroCufdSoapDto struct {
    Codigo              string
    CodigoControl       string
    CodigoPuntoVenta    *int
    CodigoSucursal      *int
    Cuis                string
    Direccion           string
    FechaVigencia       time.Time
    MensajeServicioList []MensajeServicio
    Transaccion         bool
}

Response Fields

listaRespuestasCufd
[]RespuestaListaRegistroCufdSoapDto
List of CUFD responses, one for each requested branch/point of sale
transaccion
bool
Indicates if the overall request was successful
mensajesList
[]MensajeServicio
List of global messages or errors

Individual Response Fields

codigo
string
The generated CUFD code
codigoControl
string
Control code for this CUFD
codigoSucursal
*int
Branch office code for this CUFD
codigoPuntoVenta
*int
Point of sale code for this CUFD
cuis
string
CUIS code used to generate this CUFD
direccion
string
Physical address for this location
fechaVigencia
time.Time
Expiration date of this CUFD (24 hours from generation)
transaccion
bool
Success status for this individual CUFD
mensajeServicioList
[]MensajeServicio
Messages specific to this CUFD request

Example Usage

package main

import (
    "context"
    "fmt"
    "log"
    
    "github.com/ron86i/go-siat/internal/core/domain/facturacion/codigos"
    "github.com/ron86i/go-siat/pkg/client"
    "github.com/ron86i/go-siat/pkg/config"
    "github.com/ron86i/go-siat/pkg/models"
)

func main() {
    // Initialize client
    cfg := config.Config{
        Token:   "your-api-token",
        BaseURL: "https://pilotosiatservicios.impuestos.gob.bo",
    }
    
    siatClient, err := client.NewSiatClient(cfg)
    if err != nil {
        log.Fatal(err)
    }
    
    // Define multiple branches/points of sale with their CUIS codes
    puntoVenta0 := 0
    puntoVenta1 := 1
    
    datosSolicitud := []codigos.SolicitudListaCufdDto{
        {
            CodigoSucursal:   0,
            CodigoPuntoVenta: &puntoVenta0,
            Cuis:             "CUIS-CODE-1",
        },
        {
            CodigoSucursal:   0,
            CodigoPuntoVenta: &puntoVenta1,
            Cuis:             "CUIS-CODE-2",
        },
        {
            CodigoSucursal:   1,
            CodigoPuntoVenta: &puntoVenta0,
            Cuis:             "CUIS-CODE-3",
        },
    }
    
    // Build request
    request := models.Codigos.NewCufdMasivoRequest().
        WithCodigoAmbiente(1).
        WithCodigoModalidad(1).
        WithCodigoSistema("SystemCode123").
        WithNit(1234567890).
        WithDatosSolicitud(datosSolicitud).
        Build()
    
    // Execute request
    ctx := context.Background()
    resp, err := siatClient.Codigos.SolicitudCufdMasivo(ctx, request)
    if err != nil {
        log.Fatalf("Failed to request bulk CUFD: %v", err)
    }
    
    // Process responses
    if !resp.Body.Response.RespuestaCufdMasivo.Transaccion {
        fmt.Println("Bulk CUFD request failed")
        return
    }
    
    fmt.Printf("Successfully obtained %d CUFD codes\n", 
        len(resp.Body.Response.RespuestaCufdMasivo.ListaRespuestasCufd))
    
    for i, cufdResp := range resp.Body.Response.RespuestaCufdMasivo.ListaRespuestasCufd {
        if cufdResp.Transaccion {
            fmt.Printf("CUFD %d:\n", i+1)
            fmt.Printf("  Code: %s\n", cufdResp.Codigo)
            fmt.Printf("  Control Code: %s\n", cufdResp.CodigoControl)
            fmt.Printf("  Branch: %d\n", *cufdResp.CodigoSucursal)
            fmt.Printf("  Point of Sale: %d\n", *cufdResp.CodigoPuntoVenta)
            fmt.Printf("  Address: %s\n", cufdResp.Direccion)
            fmt.Printf("  Valid until: %s\n\n", cufdResp.FechaVigencia)
        } else {
            fmt.Printf("CUFD %d failed:\n", i+1)
            for _, msg := range cufdResp.MensajeServicioList {
                fmt.Printf("  Error %d: %s\n", msg.Codigo, msg.Descripcion)
            }
        }
    }
}

Best Practices

Daily renewal required: CUFD codes expire after 24 hours. Implement an automated process to request new CUFD codes daily before the expiration time.
Early morning renewal: Request new CUFD codes early in the morning (e.g., 6 AM) to ensure they’re available before business operations begin.
CUIS dependency: Always ensure you have a valid CUIS code before requesting a CUFD. If the CUIS has expired, you must renew it first.
Store with metadata: When storing CUFD codes, also save the control code, address, and expiration time. These are needed for invoice generation and validation.

Common Errors

Invalid CUIS

If you receive an error about an invalid CUIS code, verify that:
  1. The CUIS code hasn’t expired
  2. The CUIS matches the branch/point of sale in the request
  3. The CUIS was obtained for the same environment (production vs testing)

Expired CUFD

If you try to use an expired CUFD for invoicing:
  1. Request a new CUFD immediately
  2. Update your database with the new code
  3. Retry the invoice generation

CUIS Request

Request system initialization codes (required before CUFD)

Invoice Generation

Use CUFD codes to generate invoices

Build docs developers (and LLMs) love