---
title: "Creating a Payment Challenge (Go SDK)"
canonical: "https://test.abhinandan.one/x402-payments-overview-04a296ff/go-x402-create-charge"
markdown_url: "https://test.abhinandan.one/x402-payments-overview-04a296ff/go-x402-create-charge.md"
publisher: "Primitive SDKs"
kind: "guide"
content_type: "reference"
category: "Go SDK"
parent: "x402-payments-overview-04a296ff"
description: "Client.Charge creates an x402 payment challenge as the payee, accepting either a human AmountUsdc string or a base-unit Amount for the Go SDK."
keywords: ["Client.Charge", "X402ChargeInput", "x402 payment challenge", "AmountUsdc", "GetChallenge", "PayerOrg"]
last_modified: "2026-08-11T18:54:58.434218+00:00"
published_at: "2026-08-11T18:54:58.265907+00:00"
source_files:
  - "sdk-go/x402.go"
  - "sdk-go/x402_test.go"
  - "sdk-go/README.md"
sections:
  - {anchor: "construct-the-x402-client", title: "Construct the x402 client"}
  - {anchor: "create-the-challenge", title: "Create the challenge"}
  - {anchor: "step-choose-an-amount-format", title: "Choose an amount format"}
  - {anchor: "step-call-clientcharge", title: "Call Client.Charge"}
  - {anchor: "step-hand-the-challenge-to-the-payer", title: "Hand the challenge to the payer"}
  - {anchor: "re-hydrate-a-challenge-later", title: "Re-hydrate a challenge later"}
  - {anchor: "errors", title: "Errors"}
  - {anchor: "next-steps", title: "Next steps"}
---

> Documentation index: https://test.abhinandan.one/llms.txt

# Creating a Payment Challenge (Go SDK)

Create an x402 payment challenge as the payee with Client.Charge, specifying the amount as human USDC or raw token base units, then hand the challenge to the payer.

Use `Client.Charge` when your agent is the payee and needs to request a USDC payment from another agent. It creates an [x402 payment challenge](https://test.abhinandan.one/x402-payments-overview.md) that the payer signs and settles with `Pay`.

Before calling `Charge`, register a payout address once with [`RegisterPayoutAddress`](https://test.abhinandan.one/x402-payments-overview-04a296ff/go-x402-register-payout.md). `Charge` resolves `pay_to` from that registration, so a charge without one fails.

> **Note:** This page covers the payee side (creating the challenge). The payer settles it with `client.Pay(ctx, challenge, signer)`; for the shared payment model, see [x402 Payments Overview](https://test.abhinandan.one/x402-payments-overview.md). For a payment that rides a real email thread instead of a synthetic id, see the email-native flow on the same page.

## Construct the x402 client

`Charge` is a method on `*primitive.X402Client`, the x402 payments client built with `NewX402Client`; client construction and the shared payment model are explained in [x402 Payments Overview](https://test.abhinandan.one/x402-payments-overview.md). With zero options it reads `PRIMITIVE_API_KEY` from the environment and targets the production host (`https://api.primitive.dev`).

```go
package main

import (
	"context"
	"log"
	"os"

	primitive "github.com/primitivedotdev/sdks/sdk-go"
)

func main() {
	ctx := context.Background()

	client := primitive.NewX402Client(primitive.X402ClientOptions{
		APIKey: os.Getenv("PRIMITIVE_API_KEY"),
	})

	_, err := client.Charge(ctx, primitive.X402ChargeInput{
		AmountUsdc: "0.01",
		Network:    "base-sepolia",
	})
	if err != nil {
		log.Fatal(err)
	}
}
```

## Create the challenge

### 1. Choose an amount format

Set exactly one of `AmountUsdc` (a human USDC decimal string like `"0.01"`, the documented easy path) or `Amount` (token base units, e.g. `"10000"`); see [x402 Payments Overview](https://test.abhinandan.one/x402-payments-overview.md) for how the two formats relate.

### 2. Call Client.Charge

```go
challenge, err := client.Charge(ctx, primitive.X402ChargeInput{
	AmountUsdc:  "0.01", // human USDC amount
	Network:     "base-sepolia",
	PayerOrg:    os.Getenv("PAYER_ORG_ID"), // org allowed to pay
	Description: "API call",
})
if err != nil {
	log.Fatal(err)
}
```

`Network` is `"base-sepolia"` (testnet) or `"base"` (mainnet). `PayerOrg` binds the challenge to a specific paying org and is optional. `Description` is a free-text label surfaced back to the payer.

### 3. Hand the challenge to the payer

`challenge` (a `*X402Challenge`) carries `payment_requirements` and `nonce_binding`, the exact fields the payer's `Pay` call signs over. Deliver it over any out-of-band channel (API response, dashboard, message).

## Re-hydrate a challenge later

`GetChallenge` re-hydrates an existing challenge by id, so you can retry `Pay` after a process restart without creating a duplicate:

```go
challenge, err := client.GetChallenge(ctx, challengeID)
if err != nil {
	log.Fatal(err)
}
```

> **Tip:** Need the challenge to ride a real email thread instead of a synthetic id? Use `CreateEmailChallenge` from the email-native flow described on [x402 Payments Overview](https://test.abhinandan.one/x402-payments-overview.md) instead of `Charge`.

> **Warning:** Setting both `AmountUsdc` and `Amount` on the same `X402ChargeInput`, or neither, is rejected before any network call is made. Set exactly one.

## Errors

`Charge` returns a `*primitive.X402Error` on any client-side, transport, or non-2xx server error, the shared x402 error shape described in [x402 Payments Overview](https://test.abhinandan.one/x402-payments-overview.md):

```go
import (
	"errors"
	"log"

	primitive "github.com/primitivedotdev/sdks/sdk-go"
)

challenge, err := client.Charge(ctx, primitive.X402ChargeInput{Amount: "10000"})
if err != nil {
	var x402Err *primitive.X402Error
	if errors.As(err, &x402Err) {
		log.Printf("charge failed: status=%d retryAfter=%v", x402Err.Status, x402Err.RetryAfter)
	}
	return
}
_ = challenge
```

Common `Charge`-time rejections, all local (no network call made):

- Malformed or missing amount: `Amount` must be a positive integer string; `AmountUsdc` must be a positive decimal with at most 6 decimal places.
- Both `Amount` and `AmountUsdc` set, or neither set.

See [x402 Errors](https://test.abhinandan.one/x402-payments-overview-04a296ff/go-x402-errors.md) for the full status-code reference, including retry-after handling and indeterminate-outcome cases.
