crossmint/agent-checkouts-skill · Archived

agent-checkouts

>- Buy things through the Crossmint Agent Checkouts API using a stored server-side API key. Use whenever the user wants to purchase, order, buy, or check out a product from a URL via Crossmint; run an "agentic checkout"; spend against a Crossmint server key; or set up / view / clear the Crossmint API key used for purchases. The skill stores the key locally, creates a reusable buyer profile if none exists, creates the checkout, then polls status and answers each user-action prompt (variant, ship…

First seen Jul 10, 2026

Installation

$ npx skills add crossmint/agent-checkouts-skill --skill agent-checkouts

Stronger alternatives

This repository is archived — consider an actively maintained alternative.

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

Default branch main
Open issues 0
Status Archived

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 10,439 B
  • docs SUMMARY.md 647 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 1 installs

SKILL.md

Crossmint Agent Checkouts

Buy any product from a URL through Crossmint's Agent Checkouts API, authorized by a single server-side API key (no user JWT). You store the key once; then create a buyer profile, create a checkout, and drive it to completion by answering the checkout's user-action prompts.

All API details live in [reference/agent-checkouts-api.md](reference/agent-checkouts-api.md). All calls go through scripts/checkout.mjs (Node.js 18+, no dependencies).

⚠️ Real money. Agent Checkouts run in production against real merchants.
A successful checkout places a real, paid order. Always set a maxCost.
**Submitting a user action executes immediately — there is no separate
confirmation step afterward.** Once you checkout-respond to the action that
completes the purchase, payment is charged and the order is placed. Get the
user's approval of the total before that call, not after.

The command wrapper

node scripts/checkout.mjs <command> [...]

Run from the skill directory. Every command prints JSON. The key is read from $CROSSMINTAPIKEY if set, otherwise from the stored file (~/.crossmint/agent-checkouts.json, mode 0600). The host (production vs staging) is chosen automatically from the key prefix.

Step 0 — Ensure an API key is configured

Before anything else, check:

node scripts/checkout.mjs key-status
  • If configured: true, continue.
  • If configured: false, ask the user for their Crossmint server-side API

key (starts with skproduction...). It must have all Agent Checkouts scopes enabled — the whole agent-checkouts. family (create, read, update, and the agent-checkouts.buyer-profiles. scopes). A key missing any of these fails mid-flow with a 403; if that happens, tell the user which scope to add. Store the key with:

node scripts/checkout.mjs set-key sk_production_XXXXXXXX

Store the key only when the user provides it. To rotate/remove: set-key again, or clear-key. Never print the full key back — key-status shows a masked preview.

Step 1 — Ensure a buyer profile

A buyer profile holds the reusable name / contact / shipping address so you don't re-enter it each purchase.

  • If the user already has a buyerProfileId, use it (verify with

profile-get <id>).

  • Otherwise offer to create one. Gather: first & last name, email, **phone

number**, and full shipping address. Always ask for the phone number — merchants frequently require it for shipping/delivery and order updates, and a profile without one often stalls the checkout on a user action. Then:

node scripts/checkout.mjs profile-create '{
  "label": "Home",
  "name":    { "first": "Ada", "last": "Lovelace" },
  "contact": { "email": "[email protected]", "phone": "+1 415 555 0100" },
  "shipping": {
    "addressLines": ["1 Market St"],
    "locality": "San Francisco",
    "administrativeAreaCode": "US-CA",
    "postalCode": "94105",
    "countryCode": "US"
  }
}'

Capture the returned id — that's the buyerProfileId. (administrativeAreaCode is country-prefixed ISO 3166-2, e.g. US-CA; countryCode is ISO 3166-1 alpha-2; contact.phone is a free-form string up to 40 chars — prefer E.164 like +14155550100.) You can also pass a file: profile-create @profile.json.

Step 2 — Create the checkout

Collect the purchase intent from the user and encode it in --request. The --request string is where you steer everything the merchant page will ask about. Resolve shipping method and payment method up front and put them in --request — every checkout needs both, and specifying them here keeps the run from stalling on an avoidable user action later. Cover, when relevant:

  • Variant / options — size, color, style, model, edition.
  • Quantity.
  • Shipping method — always include one. Ask the user, or fall back to a

sensible default and state it: use "cheapest shipping" unless they need it fast (then "fastest shipping") or named a carrier/tier.

  • Payment method — always include one. Ask, or default to "pay by card"

and say so. Name the method only — do not put card numbers here; if the merchant needs card details they come later as a user action.

  • Billing preference — default to "bill to the shipping address" unless

the user gives a separate billing address.

If the user hasn't specified these, don't block — apply the defaults above ("cheapest shipping, pay by card, bill to shipping address"), tell the user the defaults you used, and proceed. Only ask first when the choice clearly matters (e.g. they mentioned a deadline, or multiple cards/addresses are in play).

Shopify example — buy a specific variant, cheapest shipping, card, billing same as shipping, capped at $60:

node scripts/checkout.mjs checkout-create \
  --url "https://merchant.example/products/classic-tee" \
  --request "Buy 1 of the Medium in Black. Use the cheapest shipping method. Pay by card. Bill to the same address as shipping." \
  --buyer-profile "<buyerProfileId>" \
  --max-cost "60.00" --currency "USD"

Notes:

  • --url is required; direct_url is the only supported target kind.
  • --buyer-profile prefills name/contact/shipping from Step 1.
  • --max-cost is a hard ceiling — the checkout fails (maxcostexceeded)

rather than overspending. Always set it. Use the user's stated budget, or the expected price plus a small buffer for shipping/tax, and tell the user the cap you used.

  • --merchant-context "..." adds optional navigation hints.
  • Repeat --metadata key=value to tag the checkout.

Capture the returned checkout id.

Step 3 — Poll and answer actions until terminal

Loop:

node scripts/checkout.mjs checkout-get <checkoutId>

React to status:

status what to do
queued, running Wait ~1.5s and poll again.
awaitinguseraction Handle the action (below), then poll again.
succeeded Done. Read receipt (total, merchantOrderId, evidence.confirmationUrl). Report it.
failed Read failure.reason + failure.message. Report it; offer to retry/adjust.
cancelled Report that it was cancelled.

To pace polling from the shell you can sleep between calls, e.g. sleep 2 && node scripts/checkout.mjs checkout-get <id>.

Handling awaitinguseraction

The response contains pendingUserAction with:

  • message — a human description of what's needed.
  • responseSchema — a JSON Schema for the exact values to submit. Read it

each time; the fields vary per merchant/step. Never hardcode field names.

  • expiresAt — submit before this or the checkout fails (useractionexpired).

To build the values:

  1. Parse responseSchema (properties, required, enums, types).
  2. Fill every field you can from what you already know — the buyer profile, the

user's stated variant/shipping/payment/billing preferences, and the checkout context (e.g. pick the shipping option matching "standard", the variant matching "Medium / Black").

  1. For anything you can't infer (an ambiguous option, a required detail the user

never gave, payment/card details, a final-total confirmation), ask the user, then continue.

  1. **There is no "confirm the order" action and no undo. Submitting an action

runs it immediately — the action that completes the purchase charges payment and places the order the moment you call checkout-respond.** So before submitting any action that finalizes the buy, show the user the total (and what you're about to submit) and get explicit approval. Approve before the call — nothing asks for confirmation after it.

Submit (the actionId is pendingUserAction.id):

node scripts/checkout.mjs checkout-respond <checkoutId> <actionId> \
  --values '{ "shippingOption": "standard", "confirm": true }'
  • --values must satisfy responseSchema (respect required fields and enums).

Inline JSON or @values.json.

  • actionId goes in the path only, never in the body (the wrapper handles this).
  • Default verb is submit; pass --action cancel to abort that step if the

user declines.

After submitting, poll again. Repeat until a terminal status.

Payment / card handling

Assume a usable payment method is available to the checkout (an agent card or a single-use / virtual card supplied when the payment action appears). This skill does not create payment methods. If a user action's responseSchema asks for card details, only ever provide an agent card or a single-use / virtual card number — never a reusable PAN. Ask the user for the specific value if you don't have it.

Cancelling

node scripts/checkout.mjs checkout-cancel <checkoutId>

Command reference

Command Purpose
key-status Show whether a key is configured (masked) and its environment.
set-key <key> Store a sk... (or ck...) key locally at 0600.
clear-key Delete the stored key.
`profile-create <json\ @file>` Create a buyer profile → returns id.
profile-get <id> Retrieve a buyer profile.
`profile-update <id> <json\ @file>` Update a buyer profile.
profile-delete <id> Delete a buyer profile.
checkout-create --url ... [--request ...] [--buyer-profile ...] [--max-cost ... --currency ...] [--merchant-context ...] [--metadata k=v] Create a checkout → returns id.
checkout-get <id> Poll a checkout's status.
`checkout-respond <checkoutId> <actionId> --values <json\ @file> [--action submit\ cancel]` Answer a pending user action.
checkout-cancel <id> Cancel a checkout.