7 min read

How to Fix "UCP payment_handlers missing or empty"

Your manifest has valid JSON, correct namespace, proper origin. AI agents can even discover your store. But when they try to buy, it breaks - because your payment_handlers array is empty, missing, or declaring methods you don't support. Here's how to close the gap.

What are UCP payment_handlers?

payment_handlers is a required registry object in your UCP profile that declares every payment handler your store supports. It is required: ucp.json#/$defs/business_schema lists required: ["services", "payment_handlers"], and has since v2026-04-08.

It sits directly on the ucp object - not inside a capability. Each key is the reverse-domain name of a handler specification; each value is an array of handler entries:

{
  "ucp": {
    "version": "2026-08-25",
    "services": { "dev.ucp.shopping": [ /* ... */ ] },
    "capabilities": { "dev.ucp.shopping.checkout": [ /* ... */ ] },
    "payment_handlers": {
      "com.google.pay": [
        {
          "id": "gpay_1234",
          "version": "2026-08-25",
          "available_instruments": [{ "type": "google_pay_card" }]
        }
      ]
    }
  }
}

A handler entry requires id and version. id distinguishes multiple configurations of the same handler; available_instruments is optional, and when absent the handler is treated as supporting every instrument its schema defines.

Correction (2 September 2026). An earlier version of this page showed payment_handlers as an array of strings nested under a capabilities.payment block, alongside a spec_origin field. That shape does not exist in any published UCP release - we checked v2026-01-11, v2026-04-08 and v2026-08-25. There is no dev.ucp.shopping.payment capability. The registry above is the real one. If you built against the old example, the structure below is what to change it to.

Why this breaks AI agent purchases

AI agents don't guess payment methods. They read your declared handlers and match them against the payment credentials the user has authorized. Step by step:

  1. Agent discovers your store and reads the manifest
  2. Agent sees payment_handlers: [] (or the field is missing entirely)
  3. Agent checks: "Does this store support any payment method I can use?"
  4. Answer: "No payment methods declared."
  5. Agent tells the user the store doesn't support a payment method it can process - or simply skips your store

Even if the rest of your manifest is perfect, an empty payment_handlers array means AI agents cannot transact. Your store is discovered but unfundable - functionally the same as invisible.

The 4 types of payment_handlers failures

1. Missing entirely (most common)

No payment_handlers key on the ucp object at all. This is a schema violation, not just a gap - business_schema requires the field. UCPtools reports UCP_MISSING_PAYMENT_HANDLERS as an error from validator v3.0.0 onward. It happens most often when a platform or plugin auto-generates a skeleton profile.

2. Wrong structure (an array instead of a registry)

// WRONG - this is not the shape
{ "payment_handlers": ["com.google.pay", "com.stripe.pay"] }

A bare array of strings is not valid. The value must be an object keyed by handler namespace, whose values are arrays of handler entries carrying id and version. Nesting it under a capabilities.payment block is also wrong - there is no such capability in UCP.

3. Empty registry while advertising checkout

{ "payment_handlers": {} }

An empty registry is valid on its own - the schema sets no minProperties, and it is the honest declaration for a site that takes no payments. It becomes a defect only when the same profile also declares dev.ucp.shopping.checkout: the agent can then walk all the way to paying and find nothing to pay with.

4. Declared handlers don't match actual setup

Your profile declares com.google.pay, but your store cannot actually process it. The agent attempts the transaction and it fails. This is the hardest failure to catch - it passes structural, rules, and even network checks, because every one of those only reads what you declared. Only simulation testing finds it.

How to fix payment_handlers

Fix 1: Use the registry structure

Two handlers, each with its own entry:

"payment_handlers": {
  "com.google.pay": [
    {
      "id": "gpay_1234",
      "version": "2026-08-25",
      "available_instruments": [{ "type": "google_pay_card" }]
    }
  ],
  "dev.shopify.shop_pay": [
    { "id": "shop_pay_1", "version": "2026-08-25" }
  ]
}

If you take no payments at all, declare the registry empty rather than omitting it - "payment_handlers": {} satisfies the schema and honestly says there is nothing on offer.

Fix 2: Get the handler namespace from its author, not from a list

This is the part most guides get wrong, including an earlier version of this one. UCP does not publish a fixed registry of payment handler identifiers. A payment handler is a specification, authored by a payment provider or platform, and its namespace is the reverse-domain name that provider controls. There is no canonical table to copy from.

The identifiers named in the UCP specification itself, as examples:

Handler namespaceWhere it appears in the spec
com.google.payCore concepts + schema authoring examples
dev.shopify.shop_payCore concepts
dev.ucp.processor_tokenizerSchema authoring

For anything else - your PSP, your platform's own handler - take the namespace from that provider's handler specification. Do not guess a plausible-looking one: an identifier the agent does not recognise is a handler it cannot use.

Fix 3: Match handlers to your actual infrastructure

This is the step most guides skip. List every payment method your store actually processes, map each to its correct namespace, and declare ONLY those - no aspirational methods. Adding com.google.pay when you don't support it causes agent-side failures invisible in your own testing.

Fix 4: Verify handlers work through UCP endpoints

Your payment endpoint must receive payment requests from agents, route them to the correct handler based on the declared namespace, and return standardized responses. If your endpoint only handles a different handler or returns errors, agents fail at the network level.

How to test your fix

Payment handler failures span multiple levels. Level 1 and 2 catch empty arrays and bad namespaces. Level 3 and 4 are where the mismatch between declared handlers and actual infrastructure shows up - if you declare com.google.pay but don't support it, only a full simulation catches the failure. See the four levels of UCP validation.

Confirm agents can actually pay

Run a free 4-level validation - including the agent simulation that catches handler mismatches your own testing won't.

Validate Your Store Free