# How UCP Payment Handlers Specify Available Instruments and Constraints

> UCP payment handlers declare instruments and constraints via the available_instruments array. Learn how to specify acceptance criteria for payment methods.

- Repository: [Universal Commerce Protocol (UCP)/ucp](https://github.com/Universal-Commerce-Protocol/ucp)
- Tags: how-to-guide
- Published: 2026-04-26

---

**UCP payment handlers declare supported payment methods through the `available_instruments` array, which binds instrument types like `"card"` or `"gift_card"` to optional constraint objects that narrow acceptance criteria.**

The Universal Commerce Protocol (UCP) defines a strict schema-driven mechanism for payment handlers to advertise their capabilities. When integrating with the `Universal-Commerce-Protocol/ucp` ecosystem, handlers must explicitly enumerate which payment instruments they can process and any specific limitations—such as card brands or region restrictions—that apply to each instrument type.

## Schema Definition and Structure

### The available_instruments Field

In [`source/schemas/payment_handler.json`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/source/schemas/payment_handler.json), the core handler schema defines **`available_instruments`** as an array of objects. Each item references the `available_payment_instrument` type defined in [`source/schemas/shopping/types/available_payment_instrument.json`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/source/schemas/shopping/types/available_payment_instrument.json).

```json
"available_instruments": {
  "type": "array",
  "items": { "$ref": "shopping/types/available_payment_instrument.json" },
  "description": "Instrument types this handler supports, with optional constraints."
}

```

Every entry in this array represents a distinct payment instrument the handler is equipped to process. Omitting this field signals that the handler supports **all** instrument types defined by its underlying handler schema, though explicit declaration is recommended for clarity and security.

### Instrument Type Identification

Each instrument entry requires a **`type`** string that acts as a discriminator. Valid values correspond to concrete instrument schemas, such as `"card"` for card payments or `"gift_card"` for stored-value instruments. This identifier is defined in [`source/schemas/shopping/types/available_payment_instrument.json`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/source/schemas/shopping/types/available_payment_instrument.json) (lines 9-12) and must match the payment instrument's canonical name exactly.

```json
{
  "type": "card"
}

```

## Declaring Constraints

### Optional Constraints Object

Handlers refine generic instrument definitions using a free-form **`constraints`** object. While the base schema in [`available_payment_instrument.json`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/available_payment_instrument.json) (lines 13-18) only mandates that the object contain at least one property, instrument-specific schemas—such as `available_card_payment_instrument`—define strict sub-properties like `brands`, `issuing_countries`, or `currencies`.

The constraints object's structure varies by instrument type, allowing granular control without breaking the extensible schema contract.

### Constraint Examples

A minimal declaration accepts all variations of an instrument type:

```json
{
  "type": "card"
}

```

A constrained declaration narrows acceptance to specific card brands:

```json
{
  "type": "card",
  "constraints": {
    "brands": ["visa", "mastercard"]
  }
}

```

## Declaration Contexts and Resolution

### Platform vs Business Declarations

UCP recognizes three hierarchical contexts where `available_instruments` appears:

- **Platform schema**: The payment processor advertises its global capabilities.
- **Business schema**: The merchant declares a filtered subset of platform instruments they wish to accept.
- **Response schema**: The authoritative, resolved list delivered to the checkout frontend.

When declared in [`source/schemas/payment_handler.json`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/source/schemas/payment_handler.json) compliant configurations, these schemas layer to create a permission hierarchy.

### Runtime Resolution Flow

At checkout, the system computes the intersection of three authoritative sources:

1. **Platform-declared capabilities** (what the processor can technically handle)
2. **Business-declared list** (what the merchant chooses to offer)
3. **Checkout-specific restrictions** (session-level filters like amount limits or risk checks)

The resulting array appears in the response schema and becomes the definitive source for transaction processing. According to [`docs/specification/payment-handler-guide.md`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/docs/specification/payment-handler-guide.md), this resolution ensures that neither platforms nor businesses can unilaterally expand instrument availability beyond their mutual agreement.

## Implementation Examples

### Full Business Schema Declaration

Below is a complete handler configuration showing multiple instrument types with mixed constraint levels:

```json
{
  "id": "processor_tokenizer_1234",
  "version": "2024-03-01",
  "spec": "https://example.com/ucp/handler",
  "schema": "https://example.com/ucp/handler/schema.json",
  "available_instruments": [
    {
      "type": "card",
      "constraints": {
        "brands": ["visa", "mastercard"],
        "currencies": ["USD", "EUR"]
      }
    },
    {
      "type": "gift_card"
    }
  ],
  "config": {
    "environment": "production",
    "business_id": "biz_789"
  }
}

```

### Runtime Response Schema

After resolution, the checkout receives the definitive instrument list:

```json
{
  "id": "processor_tokenizer_1234",
  "version": "2024-03-01",
  "available_instruments": [
    {
      "type": "card",
      "constraints": {
        "brands": ["visa", "mastercard"]
      }
    }
  ],
  "config": {
    "api_version": 2,
    "environment": "production",
    "business_id": "biz_789"
  }
}

```

## Summary

- **`available_instruments`** in [`source/schemas/payment_handler.json`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/source/schemas/payment_handler.json) is the canonical field for declaring payment method support.
- Each array item requires a **`type`** discriminator and may include a **`constraints`** object for granular filtering.
- Absence of the field implies support for all instrument types defined by the handler schema.
- Resolution involves intersecting platform capabilities, business preferences, and checkout restrictions to produce the final authoritative list.
- Constraint shapes are defined by instrument-specific schemas (e.g., `available_card_payment_instrument`) rather than the base type alone.

## Frequently Asked Questions

### What happens if a handler omits the available_instruments field?

According to the payment handler guide in [`docs/specification/payment-handler-guide.md`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/docs/specification/payment-handler-guide.md), omitting `available_instruments` signals that the handler supports every instrument type defined by its underlying schema. While this provides maximum flexibility, explicit declaration is recommended to avoid ambiguous acceptance boundaries and ensure compliance with platform-specific capabilities.

### How are constraints validated against instrument types?

The base schema in [`source/schemas/shopping/types/available_payment_instrument.json`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/source/schemas/shopping/types/available_payment_instrument.json) requires only that the `constraints` object contain at least one property. Validation against specific constraint keys—such as `brands` for cards—occurs through JSON Schema references to instrument-specific definitions like [`available_card_payment_instrument.json`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/available_card_payment_instrument.json). This allows the protocol to remain extensible while enforcing strict typing per instrument.

### Can a business support instruments that the platform does not declare?

No. The resolution flow computes an intersection of platform capabilities and business declarations. If a business includes an instrument in their `available_instruments` array that the platform has not declared or has excluded, that instrument is filtered out of the final response schema. The platform serves as the capability ceiling, while the business acts as a selective filter.

### What is the resolution order during checkout resolution?

The system evaluates three layers in sequence: first, the platform's declared capabilities; second, the business's declared subset; and third, any runtime restrictions applied to the specific checkout session. The intersection of these three sets becomes the `available_instruments` array returned in the response schema, ensuring that all parties must explicitly agree on instrument availability before processing can occur.