Agentic commerce · UCP 2026-04-08 · PayPal

Agent-ready checkout for any PayPal merchant

Shopping agents are starting to buy on people's behalf through the open Universal Commerce Protocol. MCPal gives a PayPal merchant the UCP checkout endpoints those agents speak, and settles every order on PayPal with MCPal's own verbs: charge, or hold then capture_hold when the order ships, void_hold to release it, and refund. The merchant's policy limits, retry-safe PayPal request ids and the hash-chained decision log apply to agent orders exactly as they do to MCP tool calls. The same checkout also answers the Agentic Commerce Protocol (ACP) checkout_sessions API.

How an agent order flows

  1. Discover. The buyer agent reads /.well-known/ucp: REST endpoint, capabilities (checkout, fulfillment, discount, order) and payment handlers.
  2. Build the cart. POST /checkout-sessions and PUT updates. The agent sends item ids, an address and discount codes; the merchant prices everything (integer cents) and answers ready_for_complete when nothing is missing.
  3. Pay. POST /checkout-sessions/{id}/complete with a payment instrument. The merchant calls MCPal charge (or hold with "dev.mcpal.settlement": "authorize"). The MCPal orderRef is derived from the checkout id, so a retried complete can never charge twice.
  4. Policy. Totals at or above $250.00 stop at the merchant's approval rule: the checkout answers requires_escalation with a continue_url, and nothing is charged.
  5. After the sale. GET /orders/{id} shows the order with PayPal's ids. The merchant ships (capture_hold), releases (void_hold) or refunds (refund) through /orders/{id}/ship|release|refund.

A buyer agent buys coffee

The demo merchant is Coffee Club Supply. A gpt-4.1-mini agent (temperature 0) is told: “Buy two bags of coffee for under $40 in total, shipped. Ship to Sam Sandbox, 2211 N First St, San Jose, CA 95131, US (email sam.sandbox@personal.example.com). Pay with my saved PayPal sandbox payment instrument: handler_id mcpal_paypal_sandbox, type card, credential { type: token, token: sandbox-wallet-token }. Use a discount code if the merchant advertises one. Pick the cheapest shipping. Do not complete the purchase if the total is $40.00 or more.” Its only tools are the UCP operations above; it never sees PayPal or MCPal.

Recorded run, Thu, 12 Nov 2026 15:39:27 GMT (4 tool calls). Full transcript: docs/agentic-commerce-proof.md.

Statuscompleted
Total$31.19
UCP checkout / orderchk_ee71256eea53f3f20d / ord_ee29f215eedac0cc99
MCPal orderRefucp-ee71256eea53f3f20d
PayPal order id5H043375UE8541721
PayPal capture ids1EW29591SW950060R
  1. user

    Buy two bags of coffee for under $40 in total, shipped. Ship to Sam Sandbox, 2211 N First St, San Jose, CA 95131, US (email sam.sandbox@personal.example.com). Pay with my saved PayPal sandbox payment instrument: handler_id mcpal_paypal_sandbox, type card, credential { type: token, token: sandbox-wallet-token }. Use a discount code if the merchant advertises one. Pick the cheapest shipping. Do not complete the purchase if the total is $40.00 or more.

  2. agent → discover_merchant
    {}
  3. merchant ← discover_merchant
    {"endpoint":"https://mcpal.vercel.app/ucp/v1","payment_handlers":{"com.paypal.sandbox.mcpal":[{"id":"mcpal_paypal_sandbox","version":"2026-04-08","config":{"environment":"sandbox","settles_with":"MCPal charge / hold on PayPal Orders v2","note":"Any credential.token (or a card credential) is settled by MCPal on the PayPal sandbox with PayPal's published sandbox test card. The token 'fail_token' simulates a decline."},"available_instruments":[{"type":"card"}]}],"dev.ucp.mock_payment_handler":[{"id":"mock_payment_handler","version":"2026-04-08","config":{"note":"The UCP conformance suite's handler id. Same settlement path as mcpal_paypal_sandbox; 'fail_token' declines before PayPal is called."} …
  4. agent → create_checkout
    {"line_items":[{"item_id":"bag_house_blend_12oz","quantity":2}],"buyer":{"first_name":"Sam","last_name":"Sandbox","email":"sam.sandbox@personal.example.com"},"shipping_address":{"street_address":"2211 N First St","address_locality":"San Jose","address_region":"CA","postal_code":"95131","address_country":"US"},"discount_codes":["AGENT10"]}
  5. merchant ← create_checkout
    {"id":"chk_ee71256eea53f3f20d","status":"incomplete","line_items":[{"id":"li_1","item_id":"bag_house_blend_12oz","title":"House Blend whole bean, 12 oz bag","unit_price_cents":1400,"quantity":2}],"shipping":{"method_id":"shipping_1","destinations":[{"type":"shipping_address","id":"dest_1","street_address":"2211 N First St","address_locality":"San Jose","address_region":"CA","postal_code":"95131","address_country":"US"}],"selected_destination_id":"dest_1","selected_option_id":null,"options":[{"id":"std-ground","title":"Standard ground (5-7 business days)","cents":599},{"id":"express-2day","title":"Express (2 business days)","cents":1499}]},"discounts":{"codes":["AGENT10"],"applied":[{"code":" …
  6. agent → update_checkout
    {"checkout_id":"chk_ee71256eea53f3f20d","selected_shipping_option_id":"std-ground"}
  7. merchant ← update_checkout
    {"id":"chk_ee71256eea53f3f20d","status":"ready_for_complete","line_items":[{"id":"li_1","item_id":"bag_house_blend_12oz","title":"House Blend whole bean, 12 oz bag","unit_price_cents":1400,"quantity":2}],"shipping":{"method_id":"shipping_1","destinations":[{"type":"shipping_address","id":"dest_1","street_address":"2211 N First St","address_locality":"San Jose","address_region":"CA","postal_code":"95131","address_country":"US"}],"selected_destination_id":"dest_1","selected_option_id":"std-ground","options":[{"id":"std-ground","title":"Standard ground (5-7 business days)","cents":599},{"id":"express-2day","title":"Express (2 business days)","cents":1499}]},"discounts":{"codes":["AGENT10"],"app …
  8. assistant

    The total for two bags of House Blend whole bean coffee with the 10% agent discount and standard ground shipping is $31.19, which is under your $40 limit. I will now complete the purchase using your saved PayPal sandbox payment instrument.

  9. agent → complete_checkout
    {"checkout_id":"chk_ee71256eea53f3f20d","handler_id":"mcpal_paypal_sandbox","token":"sandbox-wallet-token"}
  10. merchant ← complete_checkout
    {"id":"chk_ee71256eea53f3f20d","status":"completed","line_items":[{"id":"li_1","item_id":"bag_house_blend_12oz","title":"House Blend whole bean, 12 oz bag","unit_price_cents":1400,"quantity":2}],"shipping":{"method_id":"shipping_1","destinations":[{"type":"shipping_address","id":"dest_1","street_address":"2211 N First St","address_locality":"San Jose","address_region":"CA","postal_code":"95131","address_country":"US"}],"selected_destination_id":"dest_1","selected_option_id":"std-ground","options":[{"id":"std-ground","title":"Standard ground (5-7 business days)","cents":599},{"id":"express-2day","title":"Express (2 business days)","cents":1499}]},"discounts":{"codes":["AGENT10"],"applied":[{" …
  11. assistant

    The order for two bags of House Blend whole bean coffee with standard ground shipping and a 10% discount has been completed successfully. The total was $31.19, under your $40 limit. Your order ID is ord_ee29f215eedac0cc99.

gpt-4.1-mini · PayPal · 3 runs per hour

Official UCP conformance suite: 55 passed, 14 failed, 9 skipped (78 tests)

Run on 2026-11-12 against this site with the suite's own runner (conformance @ 1201fb7, ucp-sdk 0.4.6). Every one of the 14 failures is in a feature this demo merchant does not implement and lists below as unsupported: order webhooks to the platform (7), platform-written order updates via PUT /orders (4) and the shipping-simulation endpoint (3). Checkout lifecycle, idempotency, totals, discounts, validation, fulfillment structure and card credentials all pass. Raw output and fixtures: docs/ucp-official.

Spec-derived checks

UCP spec-derived checks (our implementation of the UCP conformance modules), not the official suite run. Checks re-implemented in test/ucp-conformance.test.ts from the source of github.com/Universal-Commerce-Protocol/conformance at commit 1201fb78e85217c5f2df060066ccbb0a1d1dce0b and the UCP schemas at commit 98607bc53f6f5e43ec15b9f96b82cba4912f0fe4. The official Python suite was not executed: running its code (and installing ucp-sdk 0.4.6) was blocked by this environment's permission policy. To run it yourself: clone the conformance repo, then SERVER_URL=https://mcpal.vercel.app uv run pytest with a conformance_input.json naming bag_house_blend_12oz / bag_panama_geisha_4oz and test_fixtures.json with AGENT10 (10%), BEANS20 (20%), FIVEOFF (5.00). local: 54/54 passed · production: 54/54 passed. Unsupported modules are listed as unsupported, not counted as passes. Details: docs/ucp-conformance.md.

Official moduleCoveragelocalproductionNote
shopping/checkout/protocol_test.pycovered3/33/3
shopping/checkout/lifecycle_test.pycovered11/1111/11
shopping/checkout/idempotency_test.pycovered4/44/4
shopping/checkout/totals_test.pycovered6/66/6
shopping/checkout/business_logic_test.pypartial7/77/7test_buyer_consent not re-implemented: the buyer_consent capability is not advertised (consent is stored and echoed, not acted on).
shopping/discount/semantics_test.pycovered6/66/6
shopping/fulfillment/fulfillment_test.pypartial3/33/3Known-customer stored-address tests (5) are unsupported: the merchant keeps no customer address book. Item-based free shipping is not offered (the official test would skip).
shopping/fulfillment/structure_test.pycovered2/22/2
shopping/order/order_test.pypartial1/11/1GET /orders/{id} and expectations are checked. PUT /orders/{id} (platform-written fulfillment events and adjustments) is unsupported; shipping and refunds go through the merchant's own MCPal actions instead.
shopping/validation/validation_test.pycovered5/55/5
shopping/validation/invalid_input_test.pyunsupported--Needs PUT /orders/{id}, which is not implemented.
common/payments/card_credential_test.pycovered1/11/1The card number is never forwarded: the handler charges PayPal's published test card through MCPal.
common/payments/token_binding_test.pynot checked--A token with a binding completes (binding accepted but not verified).
common/payments/ap2_test.pyunsupported--AP2 mandates are ignored, not verified.
shopping/order/webhook_test.pyunsupported--No order webhooks are delivered to the platform.
shopping/order/webhook_structure_test.pyunsupported--No order webhooks (so no Standard Webhooks headers, retries or RFC 9421 signatures).
shopping/order/simulation_url_security_test.pyunsupported--No /testing/simulate-shipping endpoint; shipping is the merchant's POST /orders/{id}/ship (MCPal capture_hold).
MCPal extension (not UCP): ship-later settlementextra1/11/1Authorize at complete (MCPal hold), capture on ship (capture_hold), partial refund (refund).
ACP checkout_sessions (not UCP)extra4/44/4Spec-derived from the ACP 2026-04-17 OpenAPI; there is no ACP conformance suite to mirror.

Endpoints

GEThttps://mcpal.vercel.app/.well-known/ucpUCP business profile (discovery)
POSThttps://mcpal.vercel.app/ucp/v1/checkout-sessionscreate checkout
GET / PUThttps://mcpal.vercel.app/ucp/v1/checkout-sessions/{id}get / update (full replacement)
POSThttps://mcpal.vercel.app/ucp/v1/checkout-sessions/{id}/completepay: MCPal charge, or hold
POSThttps://mcpal.vercel.app/ucp/v1/checkout-sessions/{id}/cancelcancel (void_hold if anything was held)
GEThttps://mcpal.vercel.app/ucp/v1/orders/{id}order, with PayPal ids under dev.mcpal.settlement
POSThttps://mcpal.vercel.app/ucp/v1/orders/{id}/ship | release | refundmerchant actions (MCPal extension): capture_hold, void_hold, refund
POSThttps://mcpal.vercel.app/acp/checkout_sessionsACP create (same engine; Authorization: Bearer <any>, API-Version: 2026-04-17)
GET / POSThttps://mcpal.vercel.app/acp/checkout_sessions/{id}ACP get / update
POSThttps://mcpal.vercel.app/acp/checkout_sessions/{id}/complete | cancelACP complete (payment_data) / cancel

Headers: UCP-Agent (required; a version newer than 2026-04-08 gets 422), Idempotency-Key (same key + same body replays the first answer; a different body gets 409), Request-Id. Payment handlers: mcpal_paypal_sandbox and the conformance suite's mock_payment_handler; the token fail_token simulates a decline.

curl -s https://mcpal.vercel.app/.well-known/ucp

curl -s -X POST https://mcpal.vercel.app/ucp/v1/checkout-sessions \
  -H 'UCP-Agent: profile="https://agent.example/profile"' \
  -H "Idempotency-Key: $(uuidgen)" -H 'content-type: application/json' \
  -d '{"line_items":[{"item":{"id":"bag_house_blend_12oz"},"quantity":2}],
       "discounts":{"codes":["AGENT10"]},
       "fulfillment":{"methods":[{"type":"shipping","destinations":[{"id":"d1",
         "street_address":"2211 N First St","address_locality":"San Jose",
         "address_region":"CA","postal_code":"95131","address_country":"US"}],
         "groups":[{"selected_option_id":"std-ground"}]}]}}'

# then, with the returned id:
curl -s -X POST https://mcpal.vercel.app/ucp/v1/checkout-sessions/<id>/complete \
  -H 'UCP-Agent: profile="https://agent.example/profile"' \
  -H "Idempotency-Key: $(uuidgen)" -H 'content-type: application/json' \
  -d '{"payment":{"instruments":[{"id":"i1","handler_id":"mcpal_paypal_sandbox",
       "type":"card","credential":{"type":"token","token":"sandbox-wallet-token"}}]}}'

The demo merchant

Item idProductPrice
bag_house_blend_12ozHouse Blend whole bean, 12 oz bag$14.00
bag_ethiopia_yirgacheffe_12ozEthiopia Yirgacheffe whole bean, 12 oz bag$18.00
bag_decaf_colombia_12ozDecaf Colombia ground, 12 oz bag$16.00
mug_ceramic_blackCoffee Club ceramic mug, 12 oz$12.00
filters_v60_100V60 paper filters, pack of 100$8.00
bag_panama_geisha_4ozPanama Geisha whole bean, 4 oz (sold out)sold out

Shipping: Standard ground (5-7 business days) $5.99 (free from $50.00) · Express (2 business days) $14.99 · International express (5-10 business days) $29.99. Discount codes: AGENT10, BEANS20, FIVEOFF (AGENT10 is the one the profile advertises). Hosted-demo cap: $500.00 per checkout.

Terms: this is a demo merchant. Nothing ships.

Privacy: buyer names, emails and addresses sent to the demo are stored with the checkout session in private storage and used only to render it.

Not supported (yet)

Every merchant decision is in the decision log (source “merchant checkout (UCP)”).