# Agent Commerce Skill

How to book, purchase, and pay for things on behalf of humans.

## Three Patterns

### Pattern A: API (Structured, Preferred)

For services with direct API access: Duffel flights, LiteAPI hotels.

1. Search using the API tool (`flight_search`, LiteAPI MCP)
2. Present options to the human with prices and details
3. Create a checkout preview with `commerce_checkout_preview` for the exact merchant, item, amount, currency, allowed tool, and exact tool constraints
4. Human approves in a new message that exactly equals the preview's `confirmationMessage`, including checkout id, digest, merchant, amount, currency, allowed tool, and constraints
5. Commit the preview with `commerce_checkout_commit`; then call the approved payment or booking tool with the exact amount, currency, and constraints from the preview. Ouro consumes the matching authority without exposing a bearer token in the transcript.
6. Book using the API tool with passenger data from `user_profile_get`
7. Create a single-use virtual card via `stripe_create_card` when needed
8. Complete payment through the API
9. Deactivate the card via `stripe_deactivate_card`
10. Confirm booking to the human and record/read back the receipt with `commerce_receipt_get`

**Key tools**: `commerce_checkout_preview`, `commerce_checkout_commit`, `commerce_receipt_get`, `flight_search`, `flight_book`, `flight_cancel`, `user_profile_get`, `user_profile_store`, `stripe_create_card`, `stripe_deactivate_card`, `stripe_list_cards`

### Pattern B: Browser (Best-Effort)

For sites without API access, use browser automation via Playwright MCP.

1. Navigate to the booking site
2. Search for the requested service
3. Fill forms using data from `user_profile_get`
4. Create and commit a checkout preview before entering payment details
5. Use a virtual card from `stripe_create_card` for payment
6. If blocked by anti-bot measures, fall back to Pattern C
7. Complete and confirm the booking

**Limitations**: Browser automation is fragile. Sites may block, layouts change, CAPTCHAs appear. Always have Pattern C as fallback.

### Pattern C: Link-Only (Primary for Hostile Sites)

For sites that block automation or require complex human interaction.

1. Research the best options using browser tools or API tools
2. Prepare a curated link with pre-filled parameters where possible
3. Send the link to the human with a summary of what to book
4. Human completes the booking in their own browser

**When to use**: Always use Pattern C as the primary approach for sites known to block automation (most airline direct sites, hotel chains, rental car sites). Pattern B is best-effort, not reliable.

## Payment autonomy Levels

- **Level 0**: No autonomous payments. Agent researches, human pays manually.
- **Level 1**: Agent creates virtual cards, human approves each transaction explicitly.
- **Level 2**: Agent can book pre-approved items (within budget, approved categories) without per-transaction approval.
- **Level 3**: Full delegation with spending limits. Agent manages a budget and books as needed.

Default is Level 1. Level changes require explicit human approval.

## Commerce Authority

Money-moving tools (`stripe_create_card`, `flight_hold`, `flight_book`) require a one-use confirmed commerce authority. This is the local AP2-compatible primitive: an exact mandate record with merchant, amount, currency, allowed tool, exact tool constraints, reason, digest, expiry, confirmation, reservation/attempt/consumption state, and access log. `commerce_checkout_commit` confirms the authority but does not reveal a live bearer token to the model; the runtime reserves the one matching confirmed authority under a checkout lock, marks it attempted before crossing an external provider boundary, and consumes it only after the successful side effect is verified. A pre-attempt validation failure can release the reservation; an attempted Stripe/Duffel call stays non-replayable so ambiguous provider failures cannot create duplicate cards or bookings. Stripe card authority must include exact `type` and `merchant_categories` constraints so the card is counterparty/category-bound. If the tool, amount, currency, offer id, card type, merchant category, or other constraint changes, create a new preview and get a new confirmation.

## Error Handling

### Price Change Guard
Before completing a booking, verify the final price matches the approved price within 5%. If the price changed more than 5%, stop and report to the human. Never pay a price the human didn't approve.

### Partial Failure Reporting
When booking involves multiple services (e.g., flight + hotel), each service may succeed or fail independently — this is a partial failure scenario. Report the status of each service separately. **Never auto-cancel a successful booking because a related booking failed.** Let the human decide.

Example: "Flight SFO-JFK booked (confirmation: ABC123). Hotel booking failed: no availability for those dates. Would you like me to search for alternative hotels?"

### Refund Flow
If a booking fails after card creation:
1. Deactivate the virtual card immediately
2. Report the failure to the human
3. If a charge was made, note it for the human to follow up with the provider

## CAPTCHA Handling

When a CAPTCHA appears during browser automation (Pattern B):
1. Take a screenshot and send it to the human
2. Explain what page you're on and what you were trying to do
3. Ask the human to solve the CAPTCHA in their own browser
4. Switch to Pattern C (link-only) for this transaction

Never attempt to solve CAPTCHAs programmatically.

## Card Number Isolation

Card numbers must NEVER appear in:
- Tool return values shown to the model
- Nerves events or logs
- Chat messages to the human
- Any stored state or written notes

The only place card numbers exist is inside the Stripe client's internal payment flow functions, scoped to a single function call. The model only ever sees card IDs and last-4 digits.

## Profile Data Usage

Access profile data only when needed for the current transaction:
- `user_profile_get` to retrieve specific fields (never dump full profile)
- Passport data only for international bookings
- Loyalty program numbers only when booking with that program
- Emergency contact only when the booking service requires it

## Self-Test

Before first use, run the commerce self-test to verify all services are configured:
- Stripe: creates and deactivates a test virtual card
- Duffel: runs a test flight search
- LiteAPI: verifies API key in vault

Report results to the human with actionable next steps for any failures.
