Grocery search and priced carts an agent can buy one query at a time — real Kroger products, prices, and aisle locations.
git clone https://github.com/nirholas/x402-grocery
cd x402-grocery && npm install
npm run dev # http://localhost:4021
| Route | Price | What you get back |
|---|---|---|
GET /products | $0.002 | matching products with regular and promo prices, size, aisle, and stock level |
POST /cart | $0.005 | a priced cart: matched line items, substitutions, line totals, subtotal, tax, and grand total |
GET /health | free | Liveness, data source, configured rails |
GET /.well-known/x402 | free | Machine-readable discovery manifest |
Every paid route returns the purchased artifact in the 200 body — nothing is deferred to a webhook or a second fetch.
GET /productsX-PAYMENTPay in USDC on Base or Solana — your client picks. The 402 body always lists both.
USDC on base-sepolia (or base). The wallet signs an EIP-3009 authorization locally — no server round-trip.
USDC SPL transfer on solana. A facilitator sponsor pays the SOL network fee, so buyers need only USDC. Helpers at /api/x402-checkout build and wrap the transaction.
import { privateKeyToAccount } from "viem/accounts";
import { wrapFetchWithPayment } from "x402-fetch";
const payFetch = wrapFetchWithPayment(fetch, privateKeyToAccount(process.env.PRIVATE_KEY));
const res = await payFetch("http://localhost:4021/cart", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ items: [
{ query: "whole milk", quantity: 1 },
{ query: "eggs", quantity: 2 },
]}),
});
const cart = await res.json(); // priced cart, substitutions, totals
Live Kroger data is used when `KROGER_CLIENT_ID` and `KROGER_CLIENT_SECRET` are set (a free developer account at developer.kroger.com). Without them the service answers from a deterministic fixture catalog of ~30 common grocery items and labels every response `"source": "fixture"`. The shape of the response is identical either way, so an agent can develop against fixtures and switch to live data with no code change.