> ## 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.

# Accept Paychannels payments

> Get paid with Paychannels: quote a price, settle each signed payment through a facilitator, and cash out. Covers checkout, in-app, and streaming payments, plus agentic commerce over HTTP with x402.

This guide shows you how to receive Paychannels payments as a merchant. Each payment takes one facilitator call, and you never need gas or a registration to get paid. Any address you control can be a merchant.

[Accept payments](#accept-payments) covers any payment flow: checkout, in-app purchases, streaming, or metered usage. If you sell to agents over HTTP, continue to [Agentic payments with x402](#agentic-payments-with-x402), which adds the standard `402` handshake on top of the same calls.

You need a facilitator URL and a merchant address. The examples use the public demo facilitator. Payments are in USDC base units, where `1000` is \$0.001.

```bash theme={null}
FACILITATOR_URL=https://paychannels-demo.app.depoly.dev/facilitator
MY_MERCHANT=0xYourMerchantAddress
```

## Accept payments

### Quote your price

Ask the facilitator for payment terms once per product or metered resource. Put your own address in `payTo`, an identifier for what you sell in `resource`, and the price per payment in `price`:

```bash theme={null}
QUOTE=$(curl -sf -X POST "$FACILITATOR_URL/quote" \
  -H 'content-type: application/json' \
  -d "{\"resource\":\"https://shop.example.com/stream/42\",\"price\":\"1000\",\"payTo\":\"$MY_MERCHANT\"}")

TERMS=$(jq -c '[.accepts[] | select(.scheme=="batch-settlement")][0]' <<<"$QUOTE")
```

`TERMS` is what a payer signs against. It names your address, the price, the asset, and the hub. Send it to payers however your product works: in a checkout response, an app's configuration, or the first message of a stream. Quote again when you change the price or `payTo`, or when the hubs listed in the facilitator's `/meta` change. Do not edit any field in it.

### Settle each payment

For each unit the payer buys, they sign a payment for their new running total with you and send it to your server. Pass it to `/settle` together with the terms:

```bash theme={null}
REQ=$(jq -nc --argjson pl "$PAYMENT" --argjson t "$TERMS" \
  '{x402Version:2,paymentPayload:$pl,paymentRequirements:$t}')

curl -s -X POST "$FACILITATOR_URL/settle" -H 'content-type: application/json' -d "$REQ"
```

A successful payment returns a receipt:

```json theme={null}
{"success":true,"scheme":"batch-settlement","replay":false,
 "receipt":{"cumulative":"1000","delta":"1000","merchant":"0x2756…7C4f",
            "payer":"0x7319…3268","paymentId":"pay_4df9…",
            "resource":"https://shop.example.com/stream/42","seq":5120000040}}
```

The hub checks the signature, price, running total, deposit, and `payTo` inside the settle call, so you do not need a separate verification step. Deliver the unit once `success` is `true`. If it is `false`, `errorReason` says why, and nothing was charged.

A retry with the same payment ID returns the original receipt with `replay: true`, so a network failure never charges twice. If the facilitator is unreachable or times out, retry with the same payment.

<Tip>
  The payer's app can also call `/settle` itself and hand you the receipt. The payment lands in your account either way, because the hub credits the merchant named in the signed payment.
</Tip>

## Agentic payments with x402

Agents discover prices and pay over HTTP with [x402](/payment-services/agentic-payments/x402/intro). A Paychannels facilitator speaks x402 directly: the quote is already a complete `402 Payment Required` body, and payments arrive in a request header.

### Serve the quote as a 402

Quote each paid route with its absolute public URL as the `resource`:

```bash theme={null}
CACHED_402=$(curl -sf -X POST "$FACILITATOR_URL/quote" \
  -H 'content-type: application/json' \
  -d "{\"resource\":\"https://api.example.com/api/forecast\",\"price\":\"1000\",\"payTo\":\"$MY_MERCHANT\"}")
```

Its `accepts` array has two entries, both addressed to you:

| Scheme | How the payer pays | When you are paid |
| - | - | - |
| `batch-settlement` | A signed payment against their channel deposit | Accrues to your hub account, cashed out later |
| `exact` | A one-off onchain transfer | Immediately, to your address |

Return this body with status `402` to any request that arrives without a payment. It is safe to cache: send `Cache-Control: max-age=3600` and an `ETag`. Besides the cases above, quote again when a settle is declined with `unsupported-requirements`.

<Tip>
  Publish the same entries at `GET /.well-known/x402` so agents can attach a payment to their first request and skip the `402` round trip.
</Tip>

### Settle the payment header

When a request arrives with an `X-PAYMENT` header (newer x402 clients send `PAYMENT-SIGNATURE`; treat them the same), decode it, pick the matching entry from your cached `402`, and call `/settle`:

```bash theme={null}
PAYLOAD=$(base64 -d <<<"$X_PAYMENT")
SCHEME=$(jq -r .scheme <<<"$PAYLOAD")
PHUB=$(jq -r '.payload.hub // empty' <<<"$PAYLOAD")

ENTRY=$(jq -c --arg s "$SCHEME" --arg h "$PHUB" '[.accepts[]
  | select(.scheme==$s)
  | select($s=="exact" or ((.extra.contract|ascii_downcase)==($h|ascii_downcase)))][0]' <<<"$CACHED_402")

REQ=$(jq -nc --argjson pl "$PAYLOAD" --argjson e "$ENTRY" \
  '{x402Version:2,paymentPayload:$pl,paymentRequirements:$e,method:"GET"}')

curl -s -X POST "$FACILITATOR_URL/settle" -H 'content-type: application/json' -d "$REQ"
```

### Respond to the caller

Map the facilitator's answer to your HTTP response. Never serve content before a successful settle.

| Facilitator answer | Your response |
| - | - |
| `200` with `success: true` | `200` with the content. Set `X-PAYMENT-RESPONSE` (and `PAYMENT-RESPONSE`) to the base64 of `{success, transaction, network, payer, scheme, replay, receipt}`. |
| `200` with `success: false` | `402` with the `errorReason`. The payer fixes its side and retries. |
| `400` | `400`. The request is malformed. |
| `409` | `409`. The payment ID was reused with a different payment. |
| `429` | `429`, passing through `Retry-After`. Nothing was charged. |
| Unreachable, timeout, or unparseable | `503` with no content. A retry with the same payment converges to the original receipt. |

On a replayed payment (`replay: true`), serve the content again and never charge twice.

## Cash out

Payments made with `exact` are already in your wallet. Channel payments accrue to your account on the hub, and you withdraw them in two steps:

1. **Request.** Sign a withdrawal authorization and submit `requestWithdraw` to the hub's channel contract, or have anyone relay it for you. The hub reserves the amount at its next settlement.
2. **Redeem.** After the hub posts a settlement covering your reservation, call `withdrawAttested` with signatures from the hub's verifiers for an instant payout, or `withdraw` with a Merkle proof once the settlement matures.

Payouts always go to your account, whoever submits the transaction. One withdrawal covers everything every payer paid you on that hub, so hourly or daily is enough. To automate it, the hub operator can run a claim runner for your account that relays both steps on a schedule and pays the gas.

## Related

* [Try a demo](/pos/paychannels/try-a-demo): see the payer side of this flow.
* [Trust model](/pos/paychannels/trust-model): when a receipt is final and what the operator is trusted for.
* [x402 introduction](/payment-services/agentic-payments/x402/intro)
