pay.sh docs
SDKGo

Payment schemes

The two ways a pay-kit Go gate charges — fixed charge and metered usage (upto) — plus where MPP session lives.

A gate's Kind decides how it charges, and which middleware you mount. The default is a fixed charge; usage is a separate Kind gated with RequireUsage.

SchemeGateMiddlewareWhat it does
Fixed chargeGateFixed (default)client.Require(gate)Charge a fixed amount once, settled before the handler runs.
Metered usageGateUsageclient.RequireUsage(gate)Authorize a ceiling, meter actual usage, settle the real amount and refund the rest.

Usage gates settle a handler-determined amount via x402 upto, so they are x402-only and cannot carry fees, and the operator must have a signer. MPP session ships in Go but at the protocol layer (protocols/mpp/server.NewSession + SessionMiddleware), not as a paykit.Gate; subscription and x402 batch-settlement are not implemented in Go.

Fixed charge

The default gate: a fixed price the client settles over MPP or x402 (its choice). Settlement runs before your handler.

client, err := paykit.New(paykit.Config{	Network: paykit.SolanaLocalnet,	Accept:  []paykit.Protocol{paykit.X402, paykit.MPP},	MPP: paykit.MPPConfig{		Realm:                  "MyApp",		ChallengeBindingSecret: []byte("local-dev-secret"),	},})if err != nil {	panic(err)}gate := paykit.Gate{Amount: paykit.MustParseUSD("0.01"), Desc: "Stock quote"}// client.Require(gate) is func(http.Handler) http.Handler — it settles the// 402 (MPP or x402, the client's choice) before your handler runs.mux := http.NewServeMux()mux.Handle("/quote", client.Require(gate)(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {	pmt, _ := paykit.PaymentFrom(r.Context())	fmt.Fprintf(w, `{"ok":true,"paid_via":%q}`, pmt.Protocol)})))

The client side is a single call through the paying transport — see Client:

// The returned *http.Client settles a 402 transparently on any call.httpClient := x402client.NewClient(signer, rpc)resp, err := httpClient.Get("https://api.example.com/quote")if err != nil {	panic(err)}defer resp.Body.Close()body, _ := io.ReadAll(resp.Body)fmt.Println(string(body))

Metered usage (upto)

A GateUsage gate advertises Amount as the ceiling. The client opens a payment channel depositing that maximum; the handler meters real usage and reports it through the Charge meter from paykit.ChargeFrom; the gate settles the actual amount and refunds the remainder after the handler returns. This is the shape for LLM-token billing or per-byte metering.

// A usage gate advertises Amount as the authorized ceiling; the handler// reports actual consumption and the gate settles that, refunding the rest.gate := paykit.Gate{	Amount: paykit.MustParseUSD("1.00"),	Desc:   "Summarize, billed per token",	Kind:   paykit.GateUsage, // x402 upto; usage gates are x402-only}mux := http.NewServeMux()mux.Handle("/summarize", client.RequireUsage(gate)(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {	// Meter actual usage in base units; the gate settles it (clamped to the	// ceiling) after the handler returns.	if charge, ok := paykit.ChargeFrom(r.Context()); ok {		charge.Charge(50_000) // 0.05 USDC	}	w.Write([]byte(`{"summary":"..."}`))})))

On this page