Integration Examples

Integration Overview

CheckPoint enables pay-per-request micropayments using the x402 protocol. There are two integration paths depending on your role:

🏪 Merchants

Accept USDC payments for your API endpoints

  1. Return 402 Payment Required with payment details
  2. Receive payment in X-Payment header
  3. Verify/settle with CheckPoint
  4. Serve protected content

🤖 Agents

Pay for APIs automatically with USDC

  1. Request protected resource
  2. Parse 402 response
  3. Sign EIP-3009 authorization
  4. Retry with X-Payment header

Payment Flow

🤖Agent requests /api/data
🏪Returns 402 + requirements
✍️Agent signs payment
🔄Retries with X-Payment
CheckPoint verifies
💰USDC transferred

Merchant: Express.js Integration

Complete example for accepting payments in an Express.js server.

1

Install Dependencies

npm install express
2

Configure Your Wallet

Set your wallet address that will receive USDC payments.

3

Protect Your Endpoint

Return 402 when no payment, verify with CheckPoint when payment received.

4

Serve Premium Content

After successful verification, return your protected resource.

Complete Express.js ExampleJavaScript
// server.js - Express.js example
import express from 'express';

const app = express();
app.use(express.json());

// Your wallet address (receives USDC payments)
const MERCHANT_WALLET = '0xYourWalletAddress';
const CHECKPOINT_URL = 'https://checkpoint-pied.vercel.app';

// Protected endpoint that requires payment
app.get('/api/premium-data', async (req, res) => {
  const paymentHeader = req.headers['x-payment'];

  // Step 1: No payment? Return 402 with payment requirements
  if (!paymentHeader) {
    return res.status(402).json({
      x402Version: 2,
      accepts: [{
        scheme: 'exact',
        network: 'eip155:8453',  // Base mainnet
        maxAmountRequired: '10000',  // 0.01 USDC (6 decimals)
        resource: `${req.protocol}://${req.get('host')}${req.originalUrl}`,
        payTo: MERCHANT_WALLET,
        maxTimeoutSeconds: 300,
        asset: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',  // USDC on Base
        extra: {
          name: 'Premium Data API',
          description: 'Access to premium market data'
        }
      }]
    });
  }

  // Step 2: Verify the payment with CheckPoint
  try {
    const verification = await fetch(`${CHECKPOINT_URL}/api/v2/x402/verify`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        payment: paymentHeader,
        paymentPayload: {
          scheme: 'exact',
          network: 'eip155:8453',
          maxAmountRequired: '10000',
          resource: `${req.protocol}://${req.get('host')}${req.originalUrl}`,
          payTo: MERCHANT_WALLET,
          maxTimeoutSeconds: 300,
          asset: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'
        }
      })
    });

    const result = await verification.json();

    // Step 3: Check if payment is valid
    if (!result.valid) {
      return res.status(402).json({
        error: 'Payment verification failed',
        reason: result.invalidReason
      });
    }

    // Step 4: Optionally settle the payment (execute USDC transfer)
    const settlement = await fetch(`${CHECKPOINT_URL}/api/v2/x402/settle`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        payment: paymentHeader,
        paymentPayload: {
          scheme: 'exact',
          network: 'eip155:8453',
          maxAmountRequired: '10000',
          resource: `${req.protocol}://${req.get('host')}${req.originalUrl}`,
          payTo: MERCHANT_WALLET,
          maxTimeoutSeconds: 300,
          asset: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'
        }
      })
    });

    const settlementResult = await settlement.json();

    // Step 5: Payment verified! Serve the premium content
    res.json({
      data: {
        premium: true,
        message: 'Welcome to premium data!',
        marketData: { btc: 97500, eth: 3450 }
      },
      payment: {
        txHash: settlementResult.txHash,
        payer: result.payer,
        amount: '0.01 USDC'
      }
    });

  } catch (error) {
    console.error('Payment processing error:', error);
    res.status(500).json({ error: 'Payment processing failed' });
  }
});

app.listen(3001, () => console.log('Merchant server on port 3001'));

Merchant: Next.js App Router

Integration for Next.js 13+ App Router API routes.

Next.js API RouteTypeScript
// app/api/premium/route.ts - Next.js App Router example
import { NextRequest, NextResponse } from 'next/server';

const MERCHANT_WALLET = process.env.MERCHANT_WALLET!;
const CHECKPOINT_URL = 'https://checkpoint-pied.vercel.app';

export async function GET(req: NextRequest) {
  const paymentHeader = req.headers.get('x-payment');
  const resource = req.url;

  // No payment? Return 402
  if (!paymentHeader) {
    return NextResponse.json({
      x402Version: 2,
      accepts: [{
        scheme: 'exact',
        network: 'eip155:8453',
        maxAmountRequired: '10000',
        resource,
        payTo: MERCHANT_WALLET,
        maxTimeoutSeconds: 300,
        asset: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
        extra: { name: 'My API' }
      }]
    }, { status: 402 });
  }

  // Verify with CheckPoint
  const verification = await fetch(`${CHECKPOINT_URL}/api/v2/x402/verify`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      payment: paymentHeader,
      paymentPayload: {
        scheme: 'exact',
        network: 'eip155:8453',
        maxAmountRequired: '10000',
        resource,
        payTo: MERCHANT_WALLET,
        maxTimeoutSeconds: 300,
        asset: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'
      }
    })
  });

  const result = await verification.json();

  if (!result.valid) {
    return NextResponse.json({ error: result.invalidReason }, { status: 402 });
  }

  // Success! Return premium content
  return NextResponse.json({
    data: 'Your premium content here',
    payer: result.payer
  });
}

Agent: TypeScript with Viem

AI agent implementation using viem for wallet operations.

1

Install Dependencies

npm install viem
2

Configure Agent Wallet

Your agent needs a wallet with USDC on Base to pay for services.

3

Handle 402 Responses

Parse the payment requirements from the 402 response.

4

Sign EIP-3009

Create a gasless authorization signature for USDC transfer.

5

Retry with Payment

Include the signed payment in the X-Payment header.

Complete Viem AgentTypeScript
// agent.ts - AI Agent payment with viem
import { createWalletClient, http, encodeFunctionData } from 'viem';
import { base } from 'viem/chains';
import { privateKeyToAccount } from 'viem/accounts';
import { randomBytes } from 'crypto';

const AGENT_PRIVATE_KEY = process.env.AGENT_PRIVATE_KEY as `0x${string}`;
const SERVICE_URL = 'https://api.merchant.com/premium-data';

// USDC contract details for Base
const USDC_ADDRESS = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913';
const USDC_DOMAIN = {
  name: 'USD Coin',
  version: '2',
  chainId: 8453,
  verifyingContract: USDC_ADDRESS as `0x${string}`
};

const TRANSFER_TYPES = {
  TransferWithAuthorization: [
    { name: 'from', type: 'address' },
    { name: 'to', type: 'address' },
    { name: 'value', type: 'uint256' },
    { name: 'validAfter', type: 'uint256' },
    { name: 'validBefore', type: 'uint256' },
    { name: 'nonce', type: 'bytes32' }
  ]
};

async function payForService() {
  // Step 1: Request the protected resource
  console.log('Requesting protected resource...');
  const response = await fetch(SERVICE_URL);

  // Step 2: Handle 402 Payment Required
  if (response.status === 402) {
    const paymentDetails = await response.json();
    const accepted = paymentDetails.accepts[0];
    
    console.log('Payment required:', {
      amount: accepted.maxAmountRequired,
      payTo: accepted.payTo,
      network: accepted.network
    });

    // Step 3: Create wallet client
    const account = privateKeyToAccount(AGENT_PRIVATE_KEY);
    const client = createWalletClient({
      account,
      chain: base,
      transport: http()
    });

    // Step 4: Create EIP-3009 signature
    const nonce = `0x${randomBytes(32).toString('hex')}` as `0x${string}`;
    const validBefore = BigInt(Math.floor(Date.now() / 1000) + 300);

    const signature = await client.signTypedData({
      domain: USDC_DOMAIN,
      types: TRANSFER_TYPES,
      primaryType: 'TransferWithAuthorization',
      message: {
        from: account.address,
        to: accepted.payTo as `0x${string}`,
        value: BigInt(accepted.maxAmountRequired),
        validAfter: 0n,
        validBefore,
        nonce
      }
    });

    // Step 5: Create payment payload
    const payment = {
      x402Version: 2,
      scheme: 'exact',
      network: accepted.network,
      payload: {
        signature,
        authorization: {
          from: account.address,
          to: accepted.payTo,
          value: accepted.maxAmountRequired,
          validAfter: '0',
          validBefore: validBefore.toString(),
          nonce
        }
      }
    };

    // Step 6: Retry request with payment header
    console.log('Retrying with payment...');
    const paidResponse = await fetch(SERVICE_URL, {
      headers: {
        'X-Payment': Buffer.from(JSON.stringify(payment)).toString('base64')
      }
    });

    if (paidResponse.ok) {
      const data = await paidResponse.json();
      console.log('Success! Got premium data:', data);
      return data;
    } else {
      const error = await paidResponse.json();
      console.error('Payment failed:', error);
      throw new Error(error.error || 'Payment failed');
    }
  }

  // No payment needed
  return response.json();
}

// Run the agent
payForService().catch(console.error);

Agent: Using @x402-checkpoint/sdk SDK

Simplified integration using our TypeScript SDK.

1

Install SDK

npm install @x402-checkpoint/sdk viem
SDK IntegrationTypeScript
// agent-sdk.ts - Using @x402-checkpoint/sdk SDK
import { CheckPointClient } from '@x402-checkpoint/sdk';
import { createWalletClient, http } from 'viem';
import { base } from 'viem/chains';
import { privateKeyToAccount } from 'viem/accounts';
import { randomBytes } from 'crypto';

const checkpoint = new CheckPointClient({
  baseUrl: 'https://checkpoint-pied.vercel.app'
});

async function payWithSDK() {
  const account = privateKeyToAccount(process.env.AGENT_KEY as `0x${string}`);
  
  // 1. Try to access resource
  const response = await fetch('https://api.service.com/data');
  
  if (response.status !== 402) {
    return response.json();
  }
  
  const { accepts } = await response.json();
  const accepted = accepts[0];
  
  // 2. Create payment signature (simplified - use full code above for production)
  const client = createWalletClient({ account, chain: base, transport: http() });
  const nonce = `0x${randomBytes(32).toString('hex')}` as `0x${string}`;
  const validBefore = BigInt(Math.floor(Date.now() / 1000) + 300);
  
  const signature = await client.signTypedData({
    domain: { name: 'USD Coin', version: '2', chainId: 8453, verifyingContract: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913' },
    types: { TransferWithAuthorization: [
      { name: 'from', type: 'address' }, { name: 'to', type: 'address' },
      { name: 'value', type: 'uint256' }, { name: 'validAfter', type: 'uint256' },
      { name: 'validBefore', type: 'uint256' }, { name: 'nonce', type: 'bytes32' }
    ]},
    primaryType: 'TransferWithAuthorization',
    message: {
      from: account.address, to: accepted.payTo as `0x${string}`,
      value: BigInt(accepted.maxAmountRequired),
      validAfter: 0n, validBefore, nonce
    }
  });

  // 3. Verify with CheckPoint first (optional but recommended)
  const payment = Buffer.from(JSON.stringify({
    x402Version: 2, scheme: 'exact', network: accepted.network,
    payload: { signature, authorization: {
      from: account.address, to: accepted.payTo,
      value: accepted.maxAmountRequired,
      validAfter: '0', validBefore: validBefore.toString(), nonce
    }}
  })).toString('base64');

  const verification = await checkpoint.verify({
    payment,
    paymentPayload: accepted
  });

  if (!verification.valid) {
    throw new Error(`Payment invalid: ${verification.invalidReason}`);
  }

  // 4. Make payment request
  const paidResponse = await fetch('https://api.service.com/data', {
    headers: { 'X-Payment': payment }
  });

  return paidResponse.json();
}

Agent: Python Implementation

Python agent for AI/ML applications.

1

Install Dependencies

pip install requests eth-account
Python AgentPython
# agent.py - Python AI Agent example
import requests
import json
import base64
from eth_account import Account
from eth_account.messages import encode_typed_data
from secrets import token_bytes
import time

AGENT_PRIVATE_KEY = "0x..."  # Your private key
SERVICE_URL = "https://api.merchant.com/premium-data"

# USDC contract on Base
USDC_ADDRESS = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"

def pay_for_service():
    # Step 1: Request resource
    response = requests.get(SERVICE_URL)
    
    if response.status_code != 402:
        return response.json()
    
    # Step 2: Parse payment requirements
    payment_details = response.json()
    accepted = payment_details["accepts"][0]
    
    print(f"Payment required: {accepted['maxAmountRequired']} units")
    
    # Step 3: Create EIP-3009 signature
    account = Account.from_key(AGENT_PRIVATE_KEY)
    nonce = "0x" + token_bytes(32).hex()
    valid_before = int(time.time()) + 300
    
    typed_data = {
        "types": {
            "EIP712Domain": [
                {"name": "name", "type": "string"},
                {"name": "version", "type": "string"},
                {"name": "chainId", "type": "uint256"},
                {"name": "verifyingContract", "type": "address"}
            ],
            "TransferWithAuthorization": [
                {"name": "from", "type": "address"},
                {"name": "to", "type": "address"},
                {"name": "value", "type": "uint256"},
                {"name": "validAfter", "type": "uint256"},
                {"name": "validBefore", "type": "uint256"},
                {"name": "nonce", "type": "bytes32"}
            ]
        },
        "primaryType": "TransferWithAuthorization",
        "domain": {
            "name": "USD Coin",
            "version": "2",
            "chainId": 8453,
            "verifyingContract": USDC_ADDRESS
        },
        "message": {
            "from": account.address,
            "to": accepted["payTo"],
            "value": int(accepted["maxAmountRequired"]),
            "validAfter": 0,
            "validBefore": valid_before,
            "nonce": nonce
        }
    }
    
    signature = account.sign_typed_data(typed_data)
    
    # Step 4: Create payment header
    payment = {
        "x402Version": 2,
        "scheme": "exact",
        "network": accepted["network"],
        "payload": {
            "signature": signature.signature.hex(),
            "authorization": {
                "from": account.address,
                "to": accepted["payTo"],
                "value": accepted["maxAmountRequired"],
                "validAfter": "0",
                "validBefore": str(valid_before),
                "nonce": nonce
            }
        }
    }
    
    payment_header = base64.b64encode(json.dumps(payment).encode()).decode()
    
    # Step 5: Retry with payment
    paid_response = requests.get(
        SERVICE_URL,
        headers={"X-Payment": payment_header}
    )
    
    return paid_response.json()

if __name__ == "__main__":
    result = pay_for_service()
    print("Got data:", result)

cURL Examples

Quick API testing from the command line.

CheckPoint API Commandsbash
# ============================================
# CHECKPOINT API - cURL Examples
# ============================================

# 1. Check health
curl https://checkpoint-pied.vercel.app/api/health

# 2. List registered services
curl https://checkpoint-pied.vercel.app/api/discovery

# 3. Verify a payment
curl -X POST https://checkpoint-pied.vercel.app/api/v2/x402/verify \
  -H "Content-Type: application/json" \
  -d '{
    "payment": "BASE64_ENCODED_PAYMENT_HEADER",
    "paymentPayload": {
      "scheme": "exact",
      "network": "eip155:8453",
      "maxAmountRequired": "10000",
      "resource": "https://api.example.com/data",
      "payTo": "0xMerchantWallet",
      "maxTimeoutSeconds": 300,
      "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
    }
  }'

# 4. Settle a payment (execute USDC transfer)
curl -X POST https://checkpoint-pied.vercel.app/api/v2/x402/settle \
  -H "Content-Type: application/json" \
  -d '{
    "payment": "BASE64_ENCODED_PAYMENT_HEADER",
    "paymentPayload": { ... }
  }'

# 5. Batch settle (multiple payments)
curl -X POST https://checkpoint-pied.vercel.app/api/v2/x402/batch-settle \
  -H "Content-Type: application/json" \
  -d '{
    "payments": [
      { "payment": "...", "paymentPayload": { ... } },
      { "payment": "...", "paymentPayload": { ... } }
    ]
  }'

Next Steps