Skip to main content

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

The Go SDK targets Go 1.22+. It depends only on the standard library crypto packages plus golang.org/x/crypto; no third-party JWT library is pulled in.

Install

go get github.com/oid4pay/oid4ac-go

API reference

VerifyOffer(body []byte, headers SignedHeaders, jwks JWKS, opts ...VerifyOption) (*VerifyResult, error)

Verifies an RFC 9421 signed offer. The error wraps a VerifyErrorCode sentinel value (ErrSignatureExpired, ErrKeyIDUnknown, etc.) compatible with errors.Is.

VerifyMandate(sdJwtVc, kbJwt string, asJWKS JWKS, opts ...VerifyOption) (*Mandate, error)

Verifies an SD-JWT VC mandate plus KB-JWT pair.

Charge(ctx context.Context, req ChargeRequest) (*ChargeResponse, error)

Settles a charge against the AS. The request carries the JWT-AT and a DPoP private key; the SDK builds and signs the proof JWT.

Example: net/http storefront handler

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

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

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

    v, err := oid4ac.VerifyOffer(req.OfferBody, req.SignedHeaders, merchantJWKS,
        oid4ac.WithExpectedTargetURI("https://shop.example.com/oid4ac/offer/" + req.SKU),
    )
    if err != nil {
        http.Error(w, err.Error(), http.StatusBadRequest)
        return
    }

    res, err := oid4ac.Charge(r.Context(), oid4ac.ChargeRequest{
        AccessToken:    req.AccessToken,
        DPoPKey:        dpopPrivKey,
        OfferDigest:    v.BodyDigest,
        IdempotencyKey: req.IdempotencyKey,
    })
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    json.NewEncoder(w).Encode(res)
}

Algorithm whitelist

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