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

# useX402Payment

> React hook for the x402 payment protocol. Wraps fetch with automatic HTTP 402 payment handling using USDC on Starknet.

## Usage

```typescript theme={null}
const {
  x402Fetch,
  payFetch,
  signPayment,
  isPaying,
  lastTxHash,
  lastAmount,
  lastPayment,
  totalSpent,
  error,
  paymentCount,
} = useX402Payment({
  wallet,
  encryptKey: pin,
  getBearerToken: getToken,
  maxPaymentAmount: "1.00",
});
```

### Configuration

| Parameter           | Type                                       | Required | Description                                                       |
| ------------------- | ------------------------------------------ | -------- | ----------------------------------------------------------------- |
| `wallet`            | `WalletData \| null`                       | Yes      | Wallet data with `publicKey` and `encryptedPrivateKey`            |
| `encryptKey`        | `string`                                   | Yes      | PIN or passkey-derived key for signing                            |
| `getBearerToken`    | `() => Promise<string>`                    | No       | Function returning auth token (for session key path)              |
| `bearerToken`       | `string`                                   | No       | Static bearer token (alternative to `getBearerToken`)             |
| `maxPaymentAmount`  | `string`                                   | No       | Max USDC per payment in human-readable format (e.g. `"1.00"`)     |
| `maxAmount`         | `string`                                   | No       | Alias for `maxPaymentAmount`                                      |
| `allowedRecipients` | `string[]`                                 | No       | Whitelist of recipient addresses. Empty = allow all               |
| `session`           | `SessionKeyData \| null`                   | No       | Active session key for automatic payments without owner signature |
| `onPaymentComplete` | `(txHash: string, amount: string) => void` | No       | Callback fired after successful payment                           |

### Return Value

| Property       | Type                                                           | Description                                                                            |
| -------------- | -------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
| `x402Fetch`    | `(url: string, init?: RequestInit) => Promise<Response>`       | Drop-in `fetch` replacement — auto-handles 402                                         |
| `payFetch`     | Same as `x402Fetch`                                            | Alias                                                                                  |
| `signPayment`  | `(requirement: PaymentRequirement) => Promise<PaymentPayload>` | Manual payment signing for custom flows                                                |
| `isPaying`     | `boolean`                                                      | Whether a payment is in progress                                                       |
| `lastTxHash`   | `string \| null`                                               | Last payment transaction hash (session payments only — standard wallet returns `null`) |
| `lastAmount`   | `string \| null`                                               | Last payment amount in human-readable USDC                                             |
| `lastPayment`  | `LastPaymentInfo \| null`                                      | Last payment details: `{ txHash, amount, timestamp }`                                  |
| `totalSpent`   | `string`                                                       | Total USDC spent this session (e.g. `"0.030000"`)                                      |
| `error`        | `Error \| null`                                                | Error from last payment attempt                                                        |
| `paymentCount` | `number`                                                       | Total payments made this session                                                       |

## Example Implementation

```typescript theme={null}
import { useX402Payment, ChainToken } from "@chipi-stack/chipi-react";
import { useAuth } from "@clerk/nextjs";

export function PremiumApiClient({ wallet, pin }: { wallet: WalletData; pin: string }) {
  const { getToken } = useAuth();

  const {
    x402Fetch,
    isPaying,
    lastAmount,
    paymentCount,
    totalSpent,
    error,
  } = useX402Payment({
    wallet,
    encryptKey: pin,
    getBearerToken: getToken,
    maxPaymentAmount: "0.10", // Max 0.10 USDC per request
    onPaymentComplete: (txHash, amount) => {
      console.log(`Paid ${amount} USDC`);
    },
  });

  const handleQuery = async () => {
    // x402Fetch works like fetch — if the server returns 402,
    // the hook automatically signs and retries with X-PAYMENT header
    const response = await x402Fetch("https://api.example.com/premium/data");
    const data = await response.json();
    console.log("Response:", data);
  };

  return (
    <div>
      <button onClick={handleQuery} disabled={isPaying}>
        {isPaying ? "Paying..." : "Query Premium API"}
      </button>
      {lastAmount && <p>Last payment: {lastAmount} USDC</p>}
      <p>Total spent: {totalSpent} USDC ({paymentCount} payments)</p>
      {error && <p>Error: {error.message}</p>}
    </div>
  );
}
```

## Payment Flows

### Standard Wallet (no session)

1. `x402Fetch` makes initial request
2. Server returns `402` with `PAYMENT-REQUIRED` header
3. Hook parses requirement, validates against `maxPaymentAmount` and `allowedRecipients`
4. Signs SNIP-12 typed data locally via `signTypedData()` (no on-chain transaction)
5. Retries with `X-PAYMENT` header containing the signed payload
6. Facilitator settles the payment on-chain

### Session Key (automatic payments)

1. Same flow, but signs using session key via `executeTransactionWithSession()`
2. Payment executes on-chain immediately (pre-signed)
3. `lastTxHash` contains the actual transaction hash
4. No owner signature needed — session key handles it

## Security

* `maxPaymentAmount` enforced before signing — prevents overpayment
* `allowedRecipients` whitelist — prevents payment to unauthorized addresses
* Only `"exact"` scheme and `"starknet-mainnet"` network accepted
* Only USDC asset accepted (native USDC contract address validated)
* Amount validation uses BigInt math (no float precision issues)

<Note>
  Standard wallet payments return `lastTxHash: null` because the signature is SNIP-12 off-chain — the facilitator settles on-chain later. Session payments return the actual transaction hash.
</Note>
