# x402 payment instructions and retry (/guides/concepts/x402-payment-retry)

x402 lets a payer retry a protected HTTP request after the endpoint returns HTTP `402 Payment Required`. Your application forwards the three payment headers. It does not create the payer's payment proof.

| Header | Created by | Forwarded by | Sent to |
| --- | --- | --- | --- |
| `PAYMENT-REQUIRED` | Recuut | Your application, unchanged | The payer, with HTTP `402` |
| `PAYMENT-SIGNATURE` | The payer's wallet | Your application, unchanged | Recuut, on the retry |
| `PAYMENT-RESPONSE` | Recuut | Your application, unchanged | The payer, after a successful payment |

The exchange has five steps:

1. The payer calls your protected endpoint without payment proof.
2. Your application asks Recuut for access. Recuut returns HTTP `402` and `PAYMENT-REQUIRED`. Return both to the payer unchanged.
3. The payer's wallet reads the instructions, creates the payment proof, and retries the same endpoint with `PAYMENT-SIGNATURE`.
4. Your application forwards that exact `PAYMENT-SIGNATURE` value to Recuut, does the protected work, and tells Recuut whether the work succeeded or failed.
5. If payment succeeds, Recuut returns `PAYMENT-RESPONSE`. Return that exact value with the protected result.

**Important:** the merchant never creates, signs, edits, or guesses `PAYMENT-SIGNATURE`. It comes from the payer's wallet. Do not log any of these header values.

## What the encoded headers contain

Each header is base64 text. Base64 turns JSON into text that fits in an HTTP header. It is not encryption. Copy the encoded value exactly; decode it only when you need to inspect a custom HTTP integration. The examples below use x402 version 2, Base Sepolia (`eip155:84532`), and the same envelope version on the challenge and payer proof.

### PAYMENT-REQUIRED

Recuut creates this header when payment is needed. Your application returns it to the payer with the HTTP `402` response. Its decoded `accepts` entry names the network, USDC contract, amount, recipient, timeout, and exact payment scheme.


Inspect the complete encoded and decoded challenge

Encoded header value:

```text
PAYMENT-REQUIRED: eyJhY2NlcHRzIjpbeyJhbW91bnQiOiIxMDAwMCIsImFzc2V0IjoiMHgwMzZDYkQ1Mzg0MmM1NDI2NjM0ZTc5Mjk1NDFlQzIzMThmM2RDRjdlIiwiZXh0cmEiOnsibmFtZSI6IlVTREMiLCJ2ZXJzaW9uIjoiMiJ9LCJtYXhUaW1lb3V0U2Vjb25kcyI6MzAwLCJuZXR3b3JrIjoiZWlwMTU1Ojg0NTMyIiwicGF5VG8iOiIweDIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIiLCJzY2hlbWUiOiJleGFjdCJ9XSwiZXJyb3IiOiJQYXltZW50IHJlcXVpcmVkIiwiZXh0ZW5zaW9ucyI6eyJyZWN1dXQtcGF5bWVudC1yZXF1ZXN0Ijp7ImluZm8iOnsiaWQiOiJwcnFfMDAwMDAwMDAwMDAwNzAwMDgwMDAwMDAwMDAwMDAwMDAifSwic2NoZW1hIjp7InJlcXVpcmVkIjpbImlkIl0sInR5cGUiOiJvYmplY3QifX19LCJyZXNvdXJjZSI6eyJkZXNjcmlwdGlvbiI6IkdlbmVyYXRlIHBhaWQgdGV4dC4iLCJtaW1lVHlwZSI6ImFwcGxpY2F0aW9uL2pzb24iLCJ1cmwiOiJodHRwczovL21lcmNoYW50LmV4YW1wbGUvZ2VuZXJhdGUifSwieDQwMlZlcnNpb24iOjJ9
```

Decoded JSON:

```json
{
  "accepts": [
    {
      "amount": "10000",
      "asset": "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
      "extra": {"name": "USDC", "version": "2"},
      "maxTimeoutSeconds": 300,
      "network": "eip155:84532",
      "payTo": "0x2222222222222222222222222222222222222222",
      "scheme": "exact"
    }
  ],
  "error": "Payment required",
  "extensions": {
    "recuut-payment-request": {
      "info": {"id": "prq_00000000000070008000000000000000"},
      "schema": {"required": ["id"], "type": "object"}
    }
  },
  "resource": {
    "description": "Generate paid text.",
    "mimeType": "application/json",
    "url": "https://merchant.example/generate"
  },
  "x402Version": 2
}
```



### PAYMENT-SIGNATURE

The payer's wallet creates this header after it accepts one option from `PAYMENT-REQUIRED`. Your application receives it on the retry and forwards it unchanged to Recuut. It is missing on the first request and present on the paid retry.


Inspect the complete encoded and decoded payer proof

Encoded header value:

```text
PAYMENT-SIGNATURE: eyJhY2NlcHRlZCI6eyJhbW91bnQiOiIxMDAwMCIsImFzc2V0IjoiMHgwMzZDYkQ1Mzg0MmM1NDI2NjM0ZTc5Mjk1NDFlQzIzMThmM2RDRjdlIiwiZXh0cmEiOnsibmFtZSI6IlVTREMiLCJ2ZXJzaW9uIjoiMiJ9LCJtYXhUaW1lb3V0U2Vjb25kcyI6MzAwLCJuZXR3b3JrIjoiZWlwMTU1Ojg0NTMyIiwicGF5VG8iOiIweDIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIiLCJzY2hlbWUiOiJleGFjdCJ9LCJleHRlbnNpb25zIjp7InJlY3V1dC1wYXltZW50LXJlcXVlc3QiOnsiaW5mbyI6eyJpZCI6InBycV8wMDAwMDAwMDAwMDA3MDAwODAwMDAwMDAwMDAwMDAwMCJ9fX0sInBheWxvYWQiOnsiYXV0aG9yaXphdGlvbiI6eyJmcm9tIjoiMHgxMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExIn19LCJ4NDAyVmVyc2lvbiI6Mn0=
```

Decoded JSON:

```json
{
  "accepted": {
    "amount": "10000",
    "asset": "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
    "extra": {"name": "USDC", "version": "2"},
    "maxTimeoutSeconds": 300,
    "network": "eip155:84532",
    "payTo": "0x2222222222222222222222222222222222222222",
    "scheme": "exact"
  },
  "extensions": {
    "recuut-payment-request": {
      "info": {
        "id": "prq_00000000000070008000000000000000"
      }
    }
  },
  "payload": {
    "authorization": {
      "from": "0x1111111111111111111111111111111111111111"
    }
  },
  "x402Version": 2
}
```

This example shows the accepted payment option, the Recuut payment-request ID, and the payer authorization. Only the payer's wallet creates this JSON and its proof.



### PAYMENT-RESPONSE

Recuut creates this header only after payment succeeds. Your application returns it to the payer with the protected result. The Python SDK checks it and returns the receipt as a typed object.


Inspect the complete encoded response and its main decoded fields

Encoded header value:

```text
PAYMENT-RESPONSE: eyJhbW91bnQiOiIxMDAwMDAwIiwiZXJyb3JSZWFzb24iOm51bGwsImV4dGVuc2lvbnMiOnsicmVjdXV0LXJlY2VpcHQiOnsiZW52aXJvbm1lbnQiOiJ0ZXN0IiwiZW52aXJvbm1lbnRfa2V5IjoidGVzdCIsImlkIjoicmN0XzAwMDAwMDAwMDAwMDcwMDA4MDAwMDAwMDAwMDAwMDAwIiwiaXNzdWVkX2F0IjoiMjAyNi0wOC0xMlQwOTozMDowMC4wMDBaIiwicGF5bWVudCI6eyJhc3NldCI6IlVTREMiLCJhc3NldF9pZCI6IjB4MzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMyIsImF1dGhvcml6ZWRfYXRvbWljIjoiMTAwMDAwMCIsIm5ldHdvcmsiOiJlaXAxNTU6ODQ1MzIiLCJwYXllciI6IjB4MTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMSIsInJlY2lwaWVudCI6IjB4MjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMiIsInNjaGVtZSI6ImV4YWN0Iiwic2V0dGxlZF9hdG9taWMiOiIxMDAwMDAwIiwidHJhbnNhY3Rpb25faGFzaCI6IjB4YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSJ9LCJwcmljZSI6eyJjYWxjdWxhdGlvbl9tb2RlIjoiZml4ZWQiLCJjdXJyZW5jeSI6IlVTRCIsImlkIjoicHJjXzAwMDAwMDAwMDAwMDcwMDA4MDAwMDAwMDAwMDAwMDAwIiwibGFiZWwiOiJRdWFydGVybHkgcmVwb3J0IGFjY2VzcyJ9LCJyZXNvdXJjZSI6eyJpZCI6InJlc18wMDAwMDAwMDAwMDA3MDAwODAwMDAwMDAwMDAwMDAwMCIsIm5hbWUiOiJRdWFydGVybHkgcmVwb3J0IiwidXJsIjoiaHR0cHM6Ly9tZXJjaGFudC5leGFtcGxlL3JlcG9ydHMvcXVhcnRlcmx5In0sInNjaGVtYV92ZXJzaW9uIjoyLCJzZWxsZXIiOnsiaWQiOiJvcmdfMDAwMDAwMDAwMDAwNzAwMDgwMDAwMDAwMDAwMDAwMDAiLCJuYW1lIjoiQWNtZSBSZXNlYXJjaCJ9LCJ0cmFuc2FjdGlvbl9pZCI6InR4bl8wMDAwMDAwMDAwMDA3MDAwODAwMDAwMDAwMDAwMDAwMCJ9fSwibmV0d29yayI6ImVpcDE1NTo4NDUzMiIsInBheWVyIjoiMHgxMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExIiwic3VjY2VzcyI6dHJ1ZSwidHJhbnNhY3Rpb24iOiIweGFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEifQ==
```

Decoded JSON, with the main fields shown:

```json
{
  "amount": "1000000",
  "network": "eip155:84532",
  "payer": "0x1111111111111111111111111111111111111111",
  "success": true,
  "transaction": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
  "extensions": {
    "recuut-receipt": {
      "id": "rct_00000000000070008000000000000000",
      "transaction_id": "txn_00000000000070008000000000000000",
      "environment": "test",
      "environment_key": "test",
      "schema_version": 2
    }
  }
}
```

The full decoded value also contains the receipt's payment, price, resource, and seller information. A custom HTTP integration reads the receipt at `extensions["recuut-receipt"]`. Do not encode a receipt by itself; return the complete `PAYMENT-RESPONSE` value from Recuut.



[Follow the complete lifecycle →](/guides/concepts/paid-lifecycle/)
