Go Custom Client
Manual client implementation
examplegoclientadvanced
Files
2 files in this example
Custom x402 Client Implementation
Example client demonstrating how to implement x402 payment handling manually using only the core packages, without convenience wrappers like x402http.WrapHTTPClientWithPayment.
Prerequisites
- Go 1.24 or higher
- Valid EVM private key for making payments
- A running x402 server (see server examples)
Setup
- Copy
.env-exampleto.env:
cp .env-example .env
and fill required environment variables:
EVM_PRIVATE_KEY- Ethereum private key for EVM paymentsSERVER_URL- Server endpoint (defaults tohttp://localhost:4021/weather)
- Install dependencies:
go mod download
- Run the example:
go run .
Testing the Example
Start a server first:
cd ../../servers/gin
go run main.go
Then run the custom client:
cd ../../clients/custom
go run .
HTTP Headers (v2 Protocol)
| Header | Direction | Description |
|---|---|---|
PAYMENT-REQUIRED | Server → Client | 402 response with payment requirements |
PAYMENT-SIGNATURE | Client → Server | Retry request with payment payload |
PAYMENT-RESPONSE | Server → Client | 200 response with settlement details |
Payment Flow
- Initial Request — Make HTTP request to protected endpoint
- 402 Response — Server responds with requirements in
PAYMENT-REQUIREDheader - Parse Requirements — Decode requirements using version detection
- Create Payment — Use
x402Client.CreatePaymentPayload()to generate payload - Encode Payment — Base64 encode the payload for the header value
- Retry with Payment — Make new request with
PAYMENT-SIGNATUREheader - Success — Receive 200 with settlement in
PAYMENT-RESPONSEheader
Key Implementation Details
1. Setting Up the Client
import (
x402 "github.com/coinbase/x402/go"
evm "github.com/coinbase/x402/go/mechanisms/evm/exact/client"
evmsigners "github.com/coinbase/x402/go/signers/evm"
)
evmSigner, _ := evmsigners.NewClientSignerFromPrivateKey(os.Getenv("EVM_PRIVATE_KEY"))
client := x402.Newx402Client().
Register("eip155:*", evm.NewExactEvmScheme(evmSigner))
2. Detecting Payment Required
resp, _ := http.DefaultClient.Do(req)
if resp.StatusCode == http.StatusPaymentRequired {
// Extract PAYMENT-REQUIRED header
headerValue := resp.Header.Get("PAYMENT-REQUIRED")
decoded, _ := base64.StdEncoding.DecodeString(headerValue)
var paymentRequired types.PaymentRequired
json.Unmarshal(decoded, &paymentRequired)
// paymentRequired.Accepts contains the payment options
}
3. Creating Payment Payload
// Select first payment requirement
requirements := paymentRequired.Accepts[0]
// Create payment payload using the x402 client
payload, _ := x402Client.CreatePaymentPayload(ctx, requirements,
paymentRequired.Resource, paymentRequired.Extensions)
payloadBytes, _ := json.Marshal(payload)
encodedPayment := base64.StdEncoding.EncodeToString(payloadBytes)
4. Retrying with Payment
retryReq, _ := http.NewRequestWithContext(ctx, "GET", url, nil)
retryReq.Header.Set("PAYMENT-SIGNATURE", encodedPayment)
retryResp, _ := http.DefaultClient.Do(retryReq)
5. Extracting Settlement
settlementHeader := resp.Header.Get("PAYMENT-RESPONSE")
decoded, _ := base64.StdEncoding.DecodeString(settlementHeader)
var settlement x402.SettleResponse
json.Unmarshal(decoded, &settlement)
// settlement.Transaction, settlement.Network, settlement.Payer
Wrapper vs Custom Comparison
| Aspect | With Wrapper (x402http) | Custom Implementation |
|---|---|---|
| Code Complexity | ~10 lines | ~250 lines |
| Automatic Retry | ✅ Yes | ❌ Manual |
| Error Handling | ✅ Built-in | ❌ You implement |
| Header Management | ✅ Automatic | ❌ Manual |
| Flexibility | Limited | ✅ Complete control |
When to Use Custom Implementation
- Need complete control over every step of the payment flow
- Integrating with non-standard HTTP libraries (Resty, Fiber, etc.)
- Implementing custom retry/error logic
- Learning how x402 works under the hood
- Building adapters for unsupported frameworks
Protocol Versions
The example handles both v1 and v2 protocols:
V2 Protocol (recommended):
- Payment requirements in
PAYMENT-REQUIREDheader - Payment signature in
PAYMENT-SIGNATUREheader
V1 Protocol (legacy):
- Payment requirements in response body with
x402Version: 1 - Payment signature in
X-PAYMENTheader
Next Steps
- Basic HTTP Client — See the simple wrapper approach
- Server Examples — Build servers that accept payments
Related Resources
Related Content
Looking for more? Check out our other go examples or browse by client content.