UCP Checker
Guides · Retail

UCP for B2B: An Agent Buys on Net 30 Terms, Step by Step

· 3 November 2026 · 12 min read

Can an agent buy for a business with UCP today? Not with a purchase order or a quote yet: those are still proposals. But the 2026-08-25 release already has the two pieces most trade buying starts with: identity linking, so the agent shops as a known business account, and the Payment Terms extension, so that account can pay on invoice instead of by card.

We built both into a wholesale test store and sent an agent shopping, first signed out and then linked to a business account. This post walks through those runs step by step: list prices and a refusal, the link, trade prices, a Net 30 checkout, and the same order over A2A. Every request and reply shown here is from the runs.

What is UCP B2B buying today?

In the released spec, B2B buying is ordinary UCP checkout plus two common pieces. Identity linking (dev.ucp.common.identity_linking) lets a business require a linked account for some operations, and fill in what it knows about that account. Payment Terms (dev.ucp.common.payment.terms) lets a business offer a choice of when payment is due, such as pay now or Net 30, and carry the accepted term onto the order.

Quotes, price on request, invoices as a payment instrument and a B2B council are all open proposals. We cover them at the end.

The setup

The store is Fernway Wholesale on trade.ucpsandbox.com, one of our UCP Sandbox test stores. It sells cut stems in packs of 10 or 25 to business accounts only, with a 50-stem minimum. Browsing needs no account. Carts and checkouts do. The test buyer is a florist, Fernleaf Florists, with 30% off stems and Net 30 terms.

The agent is UCP Playground running Gemini 3.6 Flash with its UCP platform identity, over MCP and then A2A.

Step 1: the profile says what needs an account

Fernway's UCP profile declares identity linking with four scopes, each with a description the agent can show the buyer:

"dev.ucp.common.identity_linking": [{
  "version": "2026-08-25",
  "config": {
    "scopes": {
      "dev.ucp.shopping.cart:manage": { "description": { "plain": "Build carts for your business account at its trade prices." } },
      "dev.ucp.shopping.checkout:manage": { "description": { "plain": "Place orders on your business account: create, update, complete and cancel checkouts." } },
      "dev.ucp.shopping.order:read": { "description": { "plain": "View your account's orders: what was bought, the terms, where it is." } },
      "dev.ucp.shopping.order:manage": { "description": { "plain": "Manage your account's orders after purchase." } }
    }
  }
}]

The spec calls these hard gates: operations covered by a scope in config.scopes need a user identity token. Catalog search isn't in the list, so anyone can browse. The profile also declares dev.ucp.common.payment.terms, extending checkout and order.

Step 2: signed out, the store shows list prices and refuses a cart

The shopper asked: "I run a florist. Find red rose stems for a wedding next week, about 100 stems, and put them in a cart."

The agent searched and found Red Rose Stems, 60 cm, at the list price: $18.00 for a pack of 10. The store said so in a message: "Sign in with a linked Fernway Wholesale business account (identity linking) for your trade prices. Prices shown are list prices."

Then the agent tried create_cart for four packs of 25. The store answered 401 with a Bearer challenge:

HTTP/2 401
www-authenticate: Bearer realm="https://trade.ucpsandbox.com",
  resource_metadata="https://trade.ucpsandbox.com/.well-known/oauth-protected-resource"

Over MCP, the body is a JSON-RPC error carrying the UCP envelope (trimmed):

"error": {
  "code": -32000,
  "message": "identity_required",
  "data": {
    "ucp": { "version": "2026-08-25", "status": "error" },
    "messages": [{
      "type": "error",
      "code": "identity_required",
      "content": "Fernway Wholesale sells to business accounts only: link a business account (identity linking) to use a cart / check out. Browsing the catalogue needs no account.",
      "severity": "requires_buyer_review"
    }]
  }
}

That's the shape the spec asks for: a WWW-Authenticate: Bearer challenge on 401, with resource_metadata pointing to where the agent finds the store's authorization server. The agent tried create_checkout next and got the same answer. Then it stopped and told the shopper: four packs at $40.00 list, $160.00 in all, and "please link your Fernway Wholesale business account." It didn't try any other way round the refusal.

The signed-out run: Red Rose Stems at the list price, the store's message about trade prices, and create_cart refused with identity_required. The trace shows the 401 with its WWW-Authenticate header.

Step 3: linking the business account

Playground showed an Account card: the store offers account linking, and asks for the four scopes in its profile. Linking is plain OAuth 2.0 with PKCE: the agent reads the store's authorization server metadata, registers itself, and sends the buyer to sign in at the store. The store's token comes back to the agent, never the shopper's password.

The spec says the agent MUST request only the scopes the business declares, not a superset. Playground asked for exactly the four.

The end of the signed-out run: the agent's summary at list prices ($40.00 a pack of 25, $160.00 for 100 stems) and the Account card with the four scopes the store asks for and Link an account.

Step 4: linked, the same search shows trade prices

With the account linked, the shopper asked again, this time for the order: "I run a florist. Order 100 red rose stems for a wedding next week on our account's Net 30 terms, delivered to our saved address."

The same product came back at $12.60 for a pack of 10: Fernleaf's 30% off. The store said why: "Prices are the trade prices for Fernleaf Florists (30% off stems, 10% off sundries)." The catalog response is the same shape for both buyers. Only the prices differ, because the request carries the token.

The linked run: Red Rose Stems at the trade price, USD 12.60, with the store's messages about trade prices and pack sizes, and the trace showing search_catalog.

Playground's Discovery and negotiation tab shows what both sides agreed: release 2026-08-25, eight capabilities, the fulfillment and payment terms extensions, and the buyer account linked with four scopes.

Discovery and negotiation: the agreed release 2026-08-25, 8 of 8 capabilities active, two extensions (shopping.fulfillment and common.payment.terms), and the account linked with four scopes.

Step 5: the store fills in what it knows

The agent created the checkout with four packs of 25: $112.00 at trade prices, against $160.00 at list. It sent no address.

The spec lets a business fill fields it owns for a linked user from its own records, such as buyer and saved payment details. Fernway filled in Fernleaf's buyer details and its saved delivery address in Chicago, then asked for a delivery option. The checkout also came back with the account's payment terms, here trimmed to the payment object:

"payment": {
  "instruments": [],
  "selected_term_id": "pt_pay_now",
  "terms": [
    { "id": "pt_pay_now", "title": "Pay now",
      "schedules": [{ "id": "sched_now", "type": "immediate", "amount": 11200,
        "description": { "plain": "$112.00 due today, when the order is placed." } }] },
    { "id": "pt_net_30", "title": "Net 30",
      "description": { "plain": "On the trade account of Fernleaf Florists, invoiced when the order is placed." },
      "schedules": [{ "id": "sched_invoice", "type": "deferred", "due_at": "2026-12-03T23:59:59Z", "amount": 11200,
        "description": { "plain": "$112.00 due by 3 December 2026, 30 days after the order date, against the invoice sent to [buyer's email]. Nothing is charged today." } }] }
  ]
}

Each term is one or more schedules: an amount, and a full sentence saying when it's due. The spec has one well-known timing type, immediate. Anything else, like deferred here, means "not due at completion", and the description says when. The amounts were $112.00 because no delivery was chosen yet. And since no term was chosen yet, the store selected pay now by default, as the spec requires.

Step 6: choosing Net 30

The agent sent one update_checkout with the next-morning delivery option and the Net 30 term:

"payment": { "selected_term_id": "pt_net_30" },
"fulfillment": { "methods": [{ "groups": [{ "id": "group_1", "selected_option_id": "trade-next-day" }] }] }

Selecting a term is an ordinary checkout update, and the store's response is authoritative. The checkout came back ready to complete: $112.00 plus $25.00 delivery, $137.00 in all, with Net 30 selected.

The update_checkout request in the trace: the line items, the buyer, payment.selected_term_id pt_net_30 and the next-morning delivery option. The chat shows the checkout ready to pay at USD 137.00.

Step 7: placing the order on account

The agent completed the checkout. With Net 30 nothing is charged, so there's no card to send. The agent sent a payment object with no instruments, "payment": { "instruments": [] }, and our store accepted it for a deferred term. That follows #881, merged on main in October, which isn't in the 2026-08-25 release text yet.

The order came back as FW-7RTQL9: placed, Net 30, nothing charged, $137.00 due by 3 December 2026. The order carries payment.accepted_term, so anyone reading the order later sees what's owed and when. The spec requires the business to carry the term forward and keep its amounts equal to the order total.

The order placed: FW-7RTQL9, four packs of 25 Red Rose Stems, Net 30, nothing charged today, USD 137.00 including next-morning delivery.

Step 8: the same order over A2A

Fernway also runs a store agent. Its profile lists A2A next to REST and MCP for shopping. So we ran a reorder over A2A 1.0: "Reorder for the shop: 50 white rose stems on our Net 30 terms, delivered to our saved address."

The agent searched over MCP, then held the checkout as a conversation with the store agent over A2A. The flow was the same: the checkout started out needing details, the store filled in the account and offered Net 30, and the agent picked next-morning delivery and Net 30. Order FW-CKGI4J: two packs of 25 White Rose Stems, 50 cm, $53.20 plus $25.00 delivery, nothing charged.

The token travels with every call, so the account and the terms hold on either transport.

The A2A run mid-checkout: the conversation with the store agent over A2A 1.0, create_checkout returned incomplete with fields missing, and the store's message that this account may pay on Net 30.

The A2A order placed: FW-CKGI4J, Net 30, nothing charged, USD 78.20; the trace shows update_checkout and complete_checkout over A2A 1.0.

What's still a proposal

Most of what large buyers need isn't in the spec yet. These are all open:

  • A B2B Procurement council. The charter (#947) proposes a Domain Tech Council for requisitions, approvals, purchase orders and invoices. We covered it in UCP for B2B: a procurement council charter.
  • Quotes. A quote extension (#929) would let a business bind a quoted price to a cart or checkout.
  • Price on request. #969 proposes catalog price states that depend on who is asking, including no public price at all.
  • Invoice as a payment instrument. #957 proposes a pay-by-invoice or bank-transfer instrument type. Today Net 30 is a term, not an instrument.
  • Terms agreed elsewhere. #1029 proposes how a term accepted outside the checkout is handed into it.

What it means for stores

  • Gate with scopes, not with silence. Declare which operations need an account, and let anyone browse. A clear identity_required with a Bearer challenge lets an agent offer the link instead of giving up.
  • Say why prices change. A one-line message ("prices shown are list prices", "these are your trade prices") tells the buyer what they're looking at, on both sides of the link.
  • Write terms as sentences. Each schedule's description is what the buyer sees. Put the amount, the date and how it's paid in it.
  • Fill in what you know. A linked buyer shouldn't have to re-type the delivery address you already hold.

What it means for agent builders

  • Treat identity_required as a next step, not a failure. Follow the resource_metadata pointer and offer the buyer the link.
  • Ask for the declared scopes and no more. The spec requires it.
  • Re-read terms after every update. Amounts and term ids are checkout-scoped. The spec says not to assume a term survives a change unchanged.
  • Don't send a card for a deferred term. Read the selected term's schedules before completing.

Try it

Start a run at trade.ucpsandbox.com. The three runs are shared: signed out, linked, Net 30 over MCP and linked, Net 30 over A2A.

What we'll watch

  • Whether stores start gating trade prices and carts behind identity linking, and how they word the refusal. We track declared capabilities across every store we check.
  • How the B2B proposals above settle, and which land in a release.
  • How agents handle terms they haven't seen before. We'll keep testing and write it up.

FAQ

Does UCP support B2B purchases?

Partly. The 2026-08-25 release supports business accounts through identity linking and pay-later terms such as Net 30 through the Payment Terms extension. Quotes, purchase orders, price on request and invoice instruments are open proposals.

How does an agent get trade prices from a store?

By linking the buyer's business account. The store then answers the same catalog request with that account's prices, because the request carries the account's token.

What happens if an agent tries to buy without an account?

If the store gates carts or checkouts behind a scope, it answers 401 with identity_required and a WWW-Authenticate: Bearer challenge. The agent can then offer the buyer the link.

How does Net 30 work in UCP?

The checkout lists payment terms in payment.terms, each with schedules saying how much is due and when. The agent selects one with payment.selected_term_id in an update. The order then carries the accepted term in payment.accepted_term.

Does the agent need a card for Net 30?

Not when the whole amount is deferred. In our run the agent completed with no payment instruments. The clarification that this is allowed is merged on the spec's main branch but isn't in the 2026-08-25 release text yet.

Does this work over A2A as well as MCP?

Yes. In our runs the same account, prices and Net 30 term held over MCP and over A2A 1.0.


About UCP Checker

UCP Checker is the independent validation and observability layer for the Universal Commerce Protocol. We crawl, validate and grade every public UCP manifest we can find, run the merchant directory, the UCP Score, live adoption stats, the vertical guides and the authority-bound vendor map, and track the spec as it evolves so you don't have to — measured from two vantages (what a business declares, and what actually happens when an agent transacts), the same way for everyone, without picking winners.

Sources

Related coverage: UCP for B2B: a procurement council charter · How UCP over A2A works, step by step · How UCP's Ask works, step by step · How UCP works: a real agent buys flowers

What does a UCP agent find at your store?
Check it once and it gets its own status page.
Check a store

Keep reading

3 Nov 2026 How UCP's Ask Works: Questions Before and After a Purchase, Step by Step Guides · 10 min 31 Oct 2026 The Wix UCP Guide: How Wix Stores Work With AI Shopping Agents Guides · 10 min 30 Oct 2026 How UCP over A2A Works: Checkout With a Store’s Agent, Step by Step Guides · 9 min