Skip to main content
ACP (Agentic Commerce Protocol) is OpenAI’s protocol for in-conversation commerce. Once you implement it, a ChatGPT user can search your catalog, review a purchase summary, and confirm an order without ever leaving the chat. The protocol works through OpenAI’s function calling API: you define three tools, host the matching endpoints, and register the tools so ChatGPT knows how to invoke them.

Prerequisites

Before you start, make sure you have:
  • API endpoints you control on any stack
  • A payment processor — Stripe is the most common choice for ACP; use Razorpay if you are targeting India
  • A structured product catalog exposed through an API
  • Basic familiarity with OpenAI function calling

ACP tool definitions

You must define exactly three tools for ChatGPT to invoke: search_products, initiate_checkout, and confirm_purchase. Pass these definitions as JSON when registering with OpenAI.
Tool definitions
[
  {
    "type": "function",
    "function": {
      "name": "search_products",
      "description": "Search the product catalog by keyword, category, or price range.",
      "parameters": {
        "type": "object",
        "properties": {
          "query": { "type": "string", "description": "Search keywords" },
          "category": { "type": "string", "description": "Product category" },
          "max_price": { "type": "number", "description": "Maximum price in dollars" }
        },
        "required": ["query"]
      }
    }
  },
  {
    "type": "function",
    "function": {
      "name": "initiate_checkout",
      "description": "Create a checkout session for selected products.",
      "parameters": {
        "type": "object",
        "properties": {
          "product_id": { "type": "string" },
          "variant_id": { "type": "string" },
          "quantity": { "type": "integer", "default": 1 }
        },
        "required": ["product_id", "quantity"]
      }
    }
  },
  {
    "type": "function",
    "function": {
      "name": "confirm_purchase",
      "description": "Confirm and complete a pending checkout session.",
      "parameters": {
        "type": "object",
        "properties": {
          "checkout_id": { "type": "string" },
          "payment_token": { "type": "string", "description": "Payment token from PSP" }
        },
        "required": ["checkout_id", "payment_token"]
      }
    }
  }
]

Implement the tool endpoints

Each tool maps to one HTTP endpoint on your server. Implement all three before registering with OpenAI.

search_products

// POST /acp/tools/search_products
app.post('/acp/tools/search_products', async (req, res) => {
  const { query, category, max_price } = req.body

  const products = await db.products.search({
    q: query,
    category,
    maxPrice: max_price ? max_price * 100 : undefined, // convert to cents
    availability: 'in_stock'
  })

  res.json({
    products: products.map(p => ({
      id: p.id,
      name: p.name,
      price: `$${(p.price_cents / 100).toFixed(2)}`,
      availability: p.availability,
      summary: p.description.slice(0, 200)
    }))
  })
})

initiate_checkout

// POST /acp/tools/initiate_checkout
app.post('/acp/tools/initiate_checkout', async (req, res) => {
  const { product_id, variant_id, quantity } = req.body

  const product = await db.products.get(product_id)
  const variant = variant_id ? await db.variants.get(variant_id) : null

  // Re-check availability
  if (product.availability !== 'in_stock') {
    return res.status(409).json({
      error: { code: 'out_of_stock', message: `${product.name} is no longer available.` }
    })
  }

  const checkout = await db.checkouts.create({
    product_id, variant_id, quantity,
    expires_at: new Date(Date.now() + 15 * 60 * 1000)
  })

  res.json({
    checkout_id: checkout.id,
    summary: {
      product: product.name,
      variant: variant?.label,
      quantity,
      subtotal: `$${((product.price_cents * quantity) / 100).toFixed(2)}`,
      expires_at: checkout.expires_at
    }
  })
})

confirm_purchase

// POST /acp/tools/confirm_purchase
app.post('/acp/tools/confirm_purchase', async (req, res) => {
  const { checkout_id, payment_token } = req.body

  const checkout = await db.checkouts.get(checkout_id)
  if (!checkout || checkout.expires_at < new Date()) {
    return res.status(410).json({ error: { code: 'expired', message: 'Checkout session expired.' } })
  }

  const payment = await stripe.paymentIntents.create({
    amount: checkout.total_cents,
    currency: 'usd',
    payment_method: payment_token,
    confirm: true
  })

  const order = await db.orders.create({ checkout_id, payment_id: payment.id })

  res.json({
    order_id: order.id,
    status: 'confirmed',
    confirmation: `Order ${order.id} placed successfully.`,
    estimated_delivery: order.estimated_delivery
  })
})

Register tools with OpenAI

Pass your tool definitions in the tools array when creating a chat completion. Set tool_choice to "auto" so the model decides when to invoke them.
import OpenAI from 'openai'

const openai = new OpenAI()

const response = await openai.chat.completions.create({
  model: 'gpt-4o',
  messages: [{ role: 'user', content: 'I want to buy running shoes under $150' }],
  tools: acpToolDefinitions, // the three tools defined above
  tool_choice: 'auto'
})

Test your implementation

Work through each scenario below before connecting to a live payment processor.
1

Test search

Start a conversation asking to find products. Confirm search_products is called with the correct parameters and returns properly shaped product data.
2

Test checkout initiation

After search results appear, ask to purchase one item. Confirm initiate_checkout is called and returns a valid checkout summary including checkout_id and expires_at.
3

Test purchase confirmation

Use a Stripe test token (tok_visa) to confirm the purchase. Verify confirm_purchase returns an order_id and estimated_delivery.
4

Test error recovery

Test with an out-of-stock product, an expired checkout session, and a declined payment. Verify error messages are human-readable and the agent responds to each state gracefully.
Use the ACP Validator to run automated checks against all three endpoints at once.

Next steps

ACP end-to-end implementation

State machine, idempotency, and end-to-end validation checklist.

ACP tool endpoints reference

Full endpoint schema, required fields, and response shapes.

ACP checkout: webhooks and going live

Webhooks, idempotency middleware, and production go-live steps.

ACP instant checkout UX patterns

Conversation flows, failure states, and confirmation design.