package verifactu import ( "bytes" "crypto/tls" "encoding/xml" "fmt" "io" "net/http" ) type Config struct { Environment string CertPath string CertPass string } type Client struct { cfg Config httpClient *http.Client } func NewClient(cfg Config) *Client { tr := &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, } return &Client{ cfg: cfg, httpClient: &http.Client{Transport: tr}, } } func (c *Client) GetEndpoint() string { if c.cfg.Environment == "production" { return "https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/tikeV1.0/cont/ws/SistemaFacturacion.wsdl" } return "https://prewww2.aeat.es/static_files/common/internet/dep/aplicaciones/es/aeat/tikeV1.0/cont/ws/SistemaFacturacion.wsdl" } type XMLRequest struct { XMLName xml.Name `xml:"soapenv:Envelope"` Xmlns string `xml:"xmlns:soapenv,attr"` XmlnsXsi string `xml:"xmlns:xsi,attr"` XmlnsSum string `xml:"xmlns:sum,attr"` XmlnsSum1 string `xml:"xmlns:sum1,attr"` XmlnsXd string `xml:"xmlns:xd,attr"` Header interface{} `xml:"soapenv:Header"` Body XMLBody `xml:"soapenv:Body"` } type XMLBody struct { Content interface{} `xml:",any"` } func (c *Client) Send(xmlPayload interface{}) ([]byte, error) { var buf bytes.Buffer enc := xml.NewEncoder(&buf) err := enc.Encode(xmlPayload) if err != nil { return nil, fmt.Errorf("failed to encode XML: %w", err) } req, err := http.NewRequest("POST", c.GetEndpoint(), &buf) if err != nil { return nil, fmt.Errorf("failed to create request: %w", err) } req.Header.Set("Content-Type", "text/xml; charset=utf-8") req.Header.Set("SOAPAction", "") resp, err := c.httpClient.Do(req) if err != nil { return nil, fmt.Errorf("request failed: %w", err) } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { return nil, fmt.Errorf("failed to read response: %w", err) } if resp.StatusCode >= 400 { return nil, fmt.Errorf("HTTP error %d: %s", resp.StatusCode, string(body)) } return body, nil }