> ## Documentation Index
> Fetch the complete documentation index at: https://docs.polygon.technology/llms.txt
> Use this file to discover all available pages before exploring further.

# Try a Paychannels demo

> Try Paychannels with test money: buy one API response, pay per token, per second, and per task, pay contractors privately, and send 1,000 payments in your browser, have your agent buy an API response, or pay with signed vouchers from your terminal against Polygon's public demo hub.

The public demo hub runs on a test network with test money. You can try it three ways: click through use cases in your browser, hand a prompt to your agent, or make payments yourself from a terminal.

## In your browser

Open the [Paychannels demo](https://paychannels-demo.app.depoly.dev) and select **Get test money**. The page creates a wallet in your browser, funds it from the demo faucet, and deposits it with the hub. That deposit is the only onchain step.

Start with **Try one payment**: one click buys a response from a live x402 endpoint, and the page breaks the round trip into stages so you can see how much of it happens inside the hub. Then pick a use case:

| Use case | What happens |
| - | - |
| **Pay per token** | A model answer streams in and pays the provider every 10 tokens. Stop it and the payments stop. |
| **Pay per second** | A video pays the studio for each second watched and stops when you pause. |
| **Agent shopping** | One agent pays four providers per call from a single balance, with no accounts or API keys. |
| **P2P payouts** | You pay three contractors directly per approved task. The page then shows what you, anyone else, and the chain can each see. |
| **Payment blast** | Your browser sends 1,000 payments as fast as it can, with zero fees. |

Every use case has a **Try with your agent** button that copies a prompt for that flow. The demo's [explorer](https://paychannels-demo.app.depoly.dev/explorer) shows live traffic, a running check that every deposit is backed, settlement batches, and your own signed payment history. The [benchmarks](https://paychannels-demo.app.depoly.dev/benchmarks) page explains the 45 million payments per second fleet run.

## With your agent

The demo publishes a step-by-step payment guide for agents at [PAYING.md](https://paychannels-demo.app.depoly.dev/PAYING.md). Paste this prompt into a coding agent with shell access:

```text Buy one API response theme={null}
Read https://paychannels-demo.app.depoly.dev/PAYING.md and use x402 to buy https://paychannels-demo.app.depoly.dev/api/paid/time through a Paychannels channel. Show me the receipt from X-PAYMENT-RESPONSE and the x-tp-timing headers.
```

The agent discovers the hub, funds itself from the demo faucet, deposits, signs, and pays. The steps below are the same flow by hand.

## From your terminal

In this tutorial you will pay for an API endpoint through the demo hub. You will start with a single direct payment, then open a channel and make three payments that need no onchain transaction at all.

By the end you will have:

* A payer wallet funded with test USDC.
* A paid response from a `402`-gated endpoint.
* An open channel and three channel payments, each confirmed by a hub receipt.

It takes about five minutes.

### Before you start

You need a terminal with `curl`, `jq`, `openssl`, and `python3` (3.8 or newer), plus `cast` from [Foundry](https://getfoundry.sh/) for the channel steps.

Run every block below in the **same shell session**. Later steps read variables that earlier steps set.

### Point your shell at the demo hub

Set the demo URLs, then read the hub's configuration from the facilitator's `/meta` endpoint:

```bash theme={null}
SITE_URL=https://paychannels-demo.app.depoly.dev
FACILITATOR_URL=$SITE_URL/facilitator
DISPENSER_URL=$SITE_URL/dispenser
RPC_URL=$SITE_URL/rpc

META=$(curl -sf -A x402-agent "$FACILITATOR_URL/meta")
CHAIN_ID=$(jq -r .chainId <<<"$META")
USDC=$(jq -r .usdc <<<"$META")
HUB=$(jq -r '.hubs[0].hub' <<<"$META")
echo "chain $CHAIN_ID, hub $HUB"
```

You will see the chain ID and the address of the hub's channel contract. Every address in this tutorial comes from `/meta` or your own wallet, so nothing is hardcoded.

<Note>
  The demo sits behind a CDN that rejects requests without a `User-Agent`. Every `curl` call here sends `-A x402-agent` for that reason.
</Note>

### Create a wallet

Download the demo's signing helper. It is a single dependency-free Python file that generates keys and signs x402 payments locally:

```bash theme={null}
curl -sfO -A x402-agent "$SITE_URL/x402_exact.py"
mkdir -p .wallets && chmod 700 .wallets
PAYER=$(python3 x402_exact.py keygen --out .wallets/payer.key)
echo "$PAYER"
```

Your new address prints to the terminal. The private key is in `.wallets/payer.key` and never leaves your machine.

### Get test funds

Ask the dispenser for gas and test USDC:

```bash theme={null}
python3 x402_exact.py fund --dispenser "$DISPENSER_URL" --address "$PAYER"
```

The response shows `"usdc":"1000000000"`, which is 1,000 test USDC (USDC has 6 decimals), along with the two funding transactions.

### Make a one-off payment

Before opening a channel, buy one response with a direct x402 payment. The helper fetches the endpoint's `402`, signs a transfer authorization, and retries with the payment attached:

```bash theme={null}
python3 x402_exact.py buy --key-file .wallets/payer.key --url "$SITE_URL/api/paid/time"
```

You will see `"status": 200`, a receipt with `"success": true` and a `transaction` hash, and the endpoint's response body. This payment was one onchain transfer. That works for occasional purchases, but each one waits for a block. A channel removes that wait.

### Open a channel

A channel needs a second key. The **session key** signs every payment, while your payer key stays in control of the funds:

```bash theme={null}
S="$(cast wallet new)"
SESSION_ADDR=$(grep -oE '0x[0-9a-fA-F]{40}' <<<"$S" | head -1)
grep -oE '0x[0-9a-fA-F]{64}' <<<"$S" | head -1 > .wallets/session.key
chmod 600 .wallets/session.key
unset S
```

Approve the hub to pull 100 test USDC, then deposit it and bind your session key in the same call:

```bash theme={null}
DEPOSIT=100000000
cast send "$USDC" 'approve(address,uint256)' "$HUB" "$DEPOSIT" \
  --private-key "$(cat .wallets/payer.key)" --rpc-url "$RPC_URL"
cast send "$HUB" 'deposit(address,address,uint256)' "$PAYER" "$SESSION_ADDR" "$DEPOSIT" \
  --private-key "$(cat .wallets/payer.key)" --rpc-url "$RPC_URL"
```

Both commands print `status 1 (success)`. These are the only onchain transactions you will send from here on. Wait about ten seconds for the hub to confirm the deposit before you pay.

### Read the endpoint's price

Request the paid endpoint without a payment and pick out the channel offer:

```bash theme={null}
curl -s -A x402-agent -o q402.json "$SITE_URL/api/paid/time"
CH=$(jq -c --arg hub "$HUB" '.accepts[]
  | select(.scheme=="batch-settlement")
  | select((.extra.contract|ascii_downcase)==($hub|ascii_downcase))' q402.json)
PRICE=$(jq -r .maxAmountRequired <<<"$CH")
MERCHANT=$(jq -r .payTo <<<"$CH")
echo "price $PRICE to $MERCHANT"
```

The `402` lists two offers: `exact` (the direct payment you used earlier) and `batch-settlement` (the channel). The price is in USDC base units, so `100` is \$0.0001.

### Pay through the channel

Each channel payment is a voucher that states the new running total you have paid this merchant. Paste this function once:

```bash theme={null}
pay() {
  OLD=$(cat .wallets/cum.txt 2>/dev/null || echo 0)
  NEW=$((OLD + PRICE))
  PAYID="pay_$(openssl rand -hex 14)"
  cat > voucher.json <<EOF
{"types":{"EIP712Domain":[{"name":"name","type":"string"},{"name":"version","type":"string"},{"name":"chainId","type":"uint256"},{"name":"verifyingContract","type":"address"}],
"Voucher":[{"name":"payer","type":"address"},{"name":"merchant","type":"address"},{"name":"cumulative","type":"uint256"}]},
"primaryType":"Voucher",
"domain":{"name":"ThunderpoltHub","version":"2","chainId":$CHAIN_ID,"verifyingContract":"$HUB"},
"message":{"payer":"$PAYER","merchant":"$MERCHANT","cumulative":"$NEW"}}
EOF
  VSIG=$(cast wallet sign --private-key "$(cat .wallets/session.key)" --data --from-file voucher.json)
  XP=$(jq -nc --arg net "eip155:$CHAIN_ID" --arg p "$PAYER" --arg m "$MERCHANT" \
       --arg c "$NEW" --arg sig "$VSIG" --arg hub "$HUB" --arg id "$PAYID" \
    '{x402Version:2,scheme:"batch-settlement",network:$net,
      payload:{binding:"thunderpolt-hub/v1",voucher:{payer:$p,merchant:$m,cumulative:$c},signature:$sig,hub:$hub},
      extensions:{"payment-identifier":{id:$id}}}' | base64 | tr -d '\n')
  CODE=$(curl -s -A x402-agent -D ch.hdr -o ch.json -w '%{http_code}' \
         "$SITE_URL/api/paid/time" -H "X-PAYMENT: $XP")
  echo "HTTP $CODE"
  if [ "$CODE" = 200 ]; then
    echo "$NEW" > .wallets/cum.txt
    grep -i '^x-payment-response:' ch.hdr | sed 's/^[^:]*: *//' | tr -d '\r' | base64 -d | jq -c .receipt
  else
    cat ch.json
  fi
}
```

Now pay three times:

```bash theme={null}
pay; pay; pay
```

You will see three `HTTP 200` lines, each followed by a receipt:

```json theme={null}
{"cumulative":"100","delta":"100","merchant":"0x5E66…43F1","payer":"0x2756…7C4f","paymentId":"pay_63fe…","resource":"https://paychannels-demo.app.depoly.dev/api/paid/time","seq":5120000034}
{"cumulative":"200","delta":"100", …}
{"cumulative":"300","delta":"100", …}
```

Notice that `cumulative` climbs by the price each time while `delta` stays at `100`, and that the full x402 response has `"transaction": null`. The hub verified each voucher and returned a receipt without touching the chain. Your payments will be included in the hub's next settlement.

### What you built

You funded a wallet, paid once onchain, and then opened a channel and paid three more times with nothing but a signature. Run `pay` as many times as you like: every call costs the payer no gas.

Your running total lives in `.wallets/cum.txt`. Keep that file. If you lose it, the next payment is declined with `unauthorized-cumulative`, and you need to read your current total back from the hub before paying again.

## Next steps

* [How Paychannels work](/pos/paychannels/overview#how-paychannels-work): what happened at each step.
* [Accept Paychannels payments](/pos/paychannels/accept-payments): charge for your own endpoint.
* [Trust model](/pos/paychannels/trust-model): what your deposit and signatures commit you to.
* The demo also publishes a full agent recipe at [PAYING.md](https://paychannels-demo.app.depoly.dev/PAYING.md), including concurrent payments, resyncing your running total, and verifying payments in the [explorer](https://paychannels-demo.app.depoly.dev/explorer).
