Skip to main content

Go SDK: github.com/oid4pay/oid4ac-go

The Go SDK targets Go 1.25+. It is a verify-only merchant library: it verifies signed offers, SD-JWT VC mandates, and catalogs. It does not settle payments. Settlement is performed by the Authorization Server, reached over HTTP, never through this SDK. The SDK depends on github.com/lestrrat-go/jwx/v2 for JOSE handling plus the OpenTelemetry SDK packages.

Not published yet. The packages are not on npm, PyPI or the Go module proxy yet, so the install commands on this page do not work today. They show the names the packages will ship under.

Install

go get github.com/oid4pay/oid4ac-go

API reference

VerifyOffer(offerBody interface{}, headers OfferSignatureHeaders, merchantJWKS *JWKSet, options VerifyOfferOptions) (*VerifiedOffer, error)

Verifies an RFC 9421 signed offer. On failure the returned error is a *VerifyError carrying a Code and Message; transport failures during a JWKS fetch return a *NetworkError. Branch on the failure mode with errors.As against the concrete error type and inspect its Code.

VerifyMandate(presentation string, merchantAudience string, options VerifyMandateOptions) (*VerifiedMandate, error)

Verifies an SD-JWT VC mandate presentation. presentation is the single compact SD-JWT VC + KB-JWT string the agent posted to the merchant; merchantAudience is the merchant's resource URL. VerifyMandateContext(ctx, presentation, merchantAudience, options) is the context-aware variant.

Example: net/http storefront handler

import (
    "encoding/json"
    "errors"
    "net/http"

    oid4ac "github.com/oid4pay/oid4ac-go"
)

func offerHandler(w http.ResponseWriter, r *http.Request) {
    var req offerPayload
    if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
        http.Error(w, "bad request", http.StatusBadRequest)
        return
    }

    verified, err := oid4ac.VerifyOffer(req.OfferBody, req.SignatureHeaders, merchantJWKS,
        oid4ac.VerifyOfferOptions{
            ExpectedTargetURI: "https://shop.example.com/oid4ac/offer/" + req.SKU,
        },
    )
    if err != nil {
        var verr *oid4ac.VerifyError
        if errors.As(err, &verr) && verr.Code == "offer_signature_expired" {
            http.Error(w, "offer expired", http.StatusBadRequest)
            return
        }
        http.Error(w, err.Error(), http.StatusBadRequest)
        return
    }

    // Offer verified. The body digest is bound for the downstream
    // mandate / settlement step, which the Authorization Server
    // performs over HTTP.
    json.NewEncoder(w).Encode(map[string]string{"body_digest": verified.BodyDigest})
}

Algorithm whitelist

Identical to Node and Python: ed25519 and ecdsa-p256-sha256 for signed offers; EdDSA for mandate verification.