SDK · Go
Go
github.com/Appiasoft/compense-saas-sdk-go 1.1.0: instalación, cliente con opciones funcionales, context, parámetros, errores con errors.Is, iteradores de paginación, el subpaquete webhook y pruebas con httptest.
En esta página
| Módulo | github.com/Appiasoft/compense-saas-sdk-go (paquete compense, subpaquete webhook) |
| Versión | 1.1.0 (compense.Version) · API v1 |
| Requisitos | Go 1.21+ (iteradores range-over-func con Go 1.23+) |
| Dependencias | Solo la biblioteca estándar |
| Repositorio | Appiasoft/compense-saas-sdk-go · guías en docs/ · ejemplos en examples/ |
Instalar #
go get github.com/Appiasoft/compense-saas-sdk-go@v1.1.0
# Repositorio privado: GOPRIVATE=github.com/Appiasoft/* y credenciales de gitCliente #
import compense "github.com/Appiasoft/compense-saas-sdk-go"
client, err := compense.NewClient(os.Getenv("COMPENSE_API_KEY"),
compense.WithEnvironment(compense.Sandbox), // Production (defecto) | Sandbox | Dev
compense.WithBaseURL("https://gw.example.co"), // otra URL; gana sobre el entorno
compense.WithHTTPClient(myHTTPClient), // proxies, mTLS, tracing, pruebas (no se modifica)
compense.WithTimeout(30*time.Second), // por intento (solo cliente creado por el SDK)
compense.WithRetry(compense.RetryConfig{MaxAttempts: 3}),
compense.WithRetryWrites(false),
compense.WithUserAgent("horizonte-erp/2.0"),
compense.WithLogger(slog.Default()), // avisos de deprecación
)
if err != nil {
log.Fatal(err) // *compense.ConfigError
}El *Client es seguro para uso concurrente: crea uno por llave y reutilízalo. Cada método recibe
un context.Context primero (plazos y cancelación, también durante las esperas entre reintentos).
Convenciones #
- Servicios en
PascalCasecon los mismos espacios de nombres que Python:client.Wallet.Bills.Pay,client.Admin.HR.CreateNovelty,client.PQRS.Submit. - Parámetros opcionales en structs
*Params(pasanilsi no tienes); los campos vacíos no se envían. Booleanos opcionales concompense.Bool(true). - La
Idempotency-Keyva como opción variádica:compense.WithIdempotencyKey("..."). - Escrituras →
*compense.Transaction(Data map[string]any); lecturas → modelos (*Balance,*Resolution,*Page,*OffsetPage…) omap[string]any; todo modelo guardaRaw. - Las respuestas se decodifican con
json.Number: los números conservan sus dígitos exactos. - Montos:
compense.Amountacepta constantes de texto ("65000") oAmountFromInt,AmountFromRatyAmountFromFloat(desaconsejado). - Decisiones:
compense.DecisionApprove/compense.DecisionReject.
Errores #
Toda respuesta no 2xx es un *compense.APIError (StatusCode, Title, Detail, TraceID,
Errors(), RetryAfter, Problem). Clasifícalos con errors.Is o los helpers:
| Estado | Centinela | Helper |
|---|---|---|
| 401, 403 | ErrAuth | IsAuthError |
| 404 | ErrNotFound | IsNotFound |
| 409 | ErrIdempotencyConflict | IsIdempotencyConflict |
| 422 | ErrValidation | IsValidationError |
| 429 | ErrRateLimited | IsRateLimited |
| 502, 504 | ErrUpstream | IsUpstreamError |
| otros 5xx | ErrServer | IsServerError |
El cliente del SDK no sigue redirecciones: un 3xx llega como *APIError.
Paginación #
it := compense.NewPageIterator(ctx, func(ctx context.Context, page int) (*compense.Page, error) {
return client.Webhooks.Deliveries.List(ctx, &compense.DeliveryListParams{Status: "failed", Page: page, PageSize: 100})
})
for it.Next() {
client.Webhooks.Deliveries.Replay(ctx, fmt.Sprint(it.Item()["id"]))
}
if err := it.Err(); err != nil {
log.Fatal(err)
}
// Go 1.23+: for item, err := range it.All() { ... }NewOffsetIterator hace lo mismo con las listas limit/offset.
Webhooks #
import "github.com/Appiasoft/compense-saas-sdk-go/webhook"
http.Handle("/compense/webhooks", webhook.Handler([]string{newSecret, oldSecret},
func(ctx context.Context, ev *webhook.Event) error {
if ev.IsTest() || alreadyApplied(ev.ID) {
return nil
}
return handle(ev.Event(), ev.Resource())
}))Handler responde 401 si la verificación falla, 500 si tu función devuelve error (para que
Compense reintente) y 200 en otro caso. Fuera de net/http usa webhook.Verify(rawBody, header, secrets, opts...) o webhook.VerifyRequest(r, secrets). Opciones: WithTolerance,
WithoutTolerance, WithNow. Errores: webhook.ErrVerification (ErrSignature,
ErrTimestamp) y ErrNoSecret. Ver Verificar la firma.
Pruebas #
Levanta un httptest.Server y apunta el cliente a él:
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Header.Get("X-API-Key") != "cmp_test" {
w.WriteHeader(http.StatusUnauthorized)
return
}
w.Header().Set("Content-Type", "application/json")
fmt.Fprint(w, `{"total":"150000.00","available_cash":"150000.00","currency":"COP"}`)
}))
defer srv.Close()
client, _ := compense.NewClient("cmp_test", compense.WithBaseURL(srv.URL))
balance, _ := client.Wallet.Balance(context.Background(), "1032456789")
fmt.Println(balance.Available.Amount) // 150000.00