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


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.