Antes de empezar
Go 1.20 o superior
Una API key de pruebas de Flashpi
Guárdala en una variable de entorno, nunca en el código ni en el repositorio.
Tu certificado de firma .p12
Cargado en la cuenta de pruebas.
Tus datos de emisor
RUC, establecimiento y punto de emisión configurados en tu cuenta.
Paso 1 · Crea el módulo
mkdir facturacion && cd facturacion
go mod init facturacion
export FLASHPI_API_KEY="tu_api_key_de_pruebas"Paso 2 · Escribe main.go
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"time"
)
const baseURL = "https://api.flashpi.ec/v1"
func emitirFactura(factura map[string]any) (map[string]any, error) {
payload, err := json.Marshal(factura)
if err != nil {
return nil, err
}
req, err := http.NewRequest(http.MethodPost, baseURL+"/facturas", bytes.NewReader(payload))
if err != nil {
return nil, err
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("FLASHPI_API_KEY"))
req.Header.Set("Content-Type", "application/json")
client := &http.Client{Timeout: 30 * time.Second}
res, err := client.Do(req)
if err != nil {
return nil, err
}
defer res.Body.Close()
body, err := io.ReadAll(res.Body)
if err != nil {
return nil, err
}
if res.StatusCode >= 400 {
return nil, fmt.Errorf("flashpi %d: %s", res.StatusCode, body)
}
var resultado map[string]any
if err := json.Unmarshal(body, &resultado); err != nil {
return nil, err
}
return resultado, nil
}
func main() {
factura := map[string]any{
"comprador": map[string]any{
"tipo_identificacion": "cedula",
"identificacion": "0102030405",
"razon_social": "Cliente de ejemplo",
"email": "[email protected]",
},
"detalles": []map[string]any{
{"descripcion": "Servicio de ejemplo", "cantidad": 1, "precio_unitario": 25.0},
},
}
resultado, err := emitirFactura(factura)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
fmt.Println(resultado["estado"], resultado["clave_acceso"])
}Paso 3 · Ejecútalo
go run .Paso 4 · Hazlo robusto
- Usa un
context.Contextconhttp.NewRequestWithContextpara poder cancelar solicitudes. - Reutiliza el
http.Clienten lugar de crear uno por llamada. - Si recibes
EN_PROCESAMIENTO, consulta el estado en lugar de reenviar. - Para volumen alto, procesa con un pool de goroutines y webhooks.
Errores frecuentes
| Síntoma | Causa probable | Qué hacer | Referencia |
|---|---|---|---|
401 Unauthorized | API key ausente, inválida o de otro ambiente. | Revisa el header Authorization y que uses la key del ambiente correcto. | Ver detalle |
422 Esquema XML | Algún campo no cumple la estructura esperada. | Lee el detalle del error y corrige el campo indicado. | Ver detalle |
SRI 43 | Clave de acceso ya registrada. | No reenvíes: consulta el estado del comprobante por su clave de acceso. | Ver detalle |
SRI 70 | Clave de acceso en procesamiento. | Espera unos segundos y consulta el estado. No reenvíes el comprobante. | Ver detalle |