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

# Handle the payment response

> Decode the PAYMENT-RESPONSE header to get settlement details after a successful x402 payment.

## Handle the payment response

After a successful x402 payment, Prudra adds a `PAYMENT-RESPONSE` header to the 200 response. This header contains settlement details encoded as a base64 JSON object. An agent that needs to verify on-chain settlement should read this header.

## The PAYMENT-RESPONSE header

The header value is a base64-encoded JSON string:

```typescript theme={null}
const paymentResponse = response.headers.get('payment-response');
if (paymentResponse) {
  const settlement = JSON.parse(
    Buffer.from(paymentResponse, 'base64').toString()
  );
  console.log(settlement);
}
```

Decoded:

```json theme={null}
{
  "txHash": "0xabc123def456...",
  "settlementPending": false,
  "network": "base-mainnet",
  "paidAt": "2026-04-30T09:00:00.000Z"
}
```

## Response fields

| Field               | Type    | Description                                                                         |
| ------------------- | ------- | ----------------------------------------------------------------------------------- |
| `txHash`            | string  | The on-chain transaction hash. Verify on a Base block explorer.                     |
| `settlementPending` | boolean | `true` if the on-chain transaction hasn't been submitted yet. `false` if confirmed. |
| `network`           | string  | The chain where settlement occurred (e.g. `"base-mainnet"`)                         |
| `paidAt`            | string  | ISO timestamp when the payment was verified by Prudra                               |

## Settlement timing

x402 settlement is asynchronous. Prudra verifies the ERC-3009 signature before your handler runs, but the on-chain transaction submission happens after the response is sent.

Typical flow:

1. Agent sends `PAYMENT-SIGNATURE`
2. Prudra verifies signature (milliseconds)
3. Your handler runs
4. Prudra returns 200 with `PAYMENT-RESPONSE` header (`settlementPending: true` initially)
5. Prudra submits ERC-3009 authorization to Base (seconds later)
6. Transaction confirms on Base (\~2 seconds)
7. `txHash` is now verifiable on-chain

In most cases, `settlementPending` is already `false` by the time the agent reads the response, because Prudra starts settlement immediately after verification.

## If settlement fails

If the on-chain transaction fails (rare — this can happen if the authorization expired before submission or gas estimation failed):

* The Payment record in Prudra's database still exists (the signature was valid)
* Prudra's operations team is automatically notified
* The vault and work output are unaffected
* Contact [support@prudra.com](mailto:support@prudra.com) with the `txHash` for investigation

For the agent, this is indistinguishable from a pending settlement. The work is complete and the vault is accessible regardless.

## Reading the response in the full flow

```typescript theme={null}
import { signX402Payment, decodePaymentRequirements, selectPaymentOption } from '@prudra/payments';
import { ethers } from 'ethers';

const agentWallet = new ethers.Wallet(process.env.AGENT_PRIVATE_KEY!);

// 1. Get 402 challenge
const r1 = await fetch('https://your-api.com/analyse', { method: 'POST', ... });
// r1.status === 402

// 2. Sign and resubmit
const requirements = decodePaymentRequirements(r1.headers.get('payment-required')!);
const option = selectPaymentOption(requirements, 'USDC');
const { xPaymentHeader } = await signX402Payment(agentWallet, option);

const r2 = await fetch('https://your-api.com/analyse', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json', 'PAYMENT-SIGNATURE': xPaymentHeader },
  body: JSON.stringify({ text: 'analyse this' }),
});
// r2.status === 200

// 3. Read the result
const result = await r2.json();
console.log('Vault ID:', result.vaultId);

// 4. Read settlement details
const paymentResponseHeader = r2.headers.get('payment-response');
if (paymentResponseHeader) {
  const settlement = JSON.parse(Buffer.from(paymentResponseHeader, 'base64').toString());
  
  if (settlement.settlementPending) {
    console.log('Settlement in progress — txHash will be confirmed shortly');
  } else {
    console.log('Settled on-chain:', settlement.txHash);
  }
}
```

## Related

* [How x402 works](/payments/x402/how-it-works) — the full ERC-3009 settlement flow
* [Test x402 payments](/payments/x402/test) — run the full test including response parsing
* [Replay attack protection](/payments/security/replay) — how Prudra prevents double-spending
