Use this skill to read Stripe account state and, with explicit confirmation, perform guarded mutations: account balance, payment intents, subscriptions, and subscription cancellation. This is a tool skill for the Stripe platform. Building Stripe payments into an application is integration development; this skill owns the everyday agent workflow: answering "what is our balance?", "which payments succeeded?", "what subscriptions are active?", and applying a confirmed cancellation.
Operating contract
- Read-only first. Balance, payment, and subscription queries run freely and never change anything. The bundled
stripe-cliscript's primary surface is these reads. - Guard every mutation. State-changing operations — canceling a subscription — require an explicit human directive plus
--dry-runpreview and--yesconfirmation throughstripe-cli. Cancellations are financial actions with billing consequences: confirm the subscription, the timing, and the impact before acting. - Respect bounded reads. Stripe paginates with
limitandhas_more; never page past what the task needs.stripe-cli --limitcaps every listing. - Keep evidence bounded. Quote short IDs, amounts, and statuses; never dump full API keys, customer data, or raw payloads into chat. Amounts are formatted by currency and JSON retains the raw integer and currency for audit.
- Treat money data as sensitive. Balances, payments, and subscription details are financial records; quote only what the question needs and never expose full card or customer data.
The stripe-cli script
scripts/stripe-cli is an agent-first, stdlib-only CLI over the Stripe API. It is read-only-first: balance, payments, and subscriptions are the primary surface; the only mutation is guarded.
stripe/scripts/stripe-cli --help # no key or network needed
stripe/scripts/stripe-cli --json balance show
stripe/scripts/stripe-cli --json --limit 20 payments list
stripe/scripts/stripe-cli --json --limit 20 subscriptions list
stripe/scripts/stripe-cli --json subscriptions get --id sub_123
stripe/scripts/stripe-cli subscriptions cancel --id sub_123 --dry-run # preview
stripe/scripts/stripe-cli subscriptions cancel --id sub_123 --yes # confirmed
Exit codes: 0 success, 1 API error or failed check, 2 usage error. Cancellations are guarded: without --dry-run or --yes the script refuses with exit 1 and never calls the API. Reads are bounded by --limit (default 20, max 100).
Operating loop
- Scope the question: is this a read (balance, payments, subscriptions) or a mutation (cancel)? Locate the object with the read surface first.
- Read with bounds:
balance showfor available and pending funds;payments listfor recent payment intents;subscriptions list/subscriptions getfor active subscriptions and their items. - Triage the answer: map the question to evidence (amounts, statuses, customers, period end dates).
- Act with confirmation: only a human directive to change, previewed with
--dry-runand confirmed with--yes. - Verify: re-read the subscription and confirm
cancel_at_period_endis set (cancellation at period end) — and state that the customer keeps service until that date.
Read surface: balance, payments, subscriptions
- Balance (
GET /balance): available and pending balances per currency. A read-only snapshot of account funds. - Payments (
GET /payment_intents): recent payment intents with amount, currency, status (succeeded,requires_action, etc.), and customer. Bounded by--limit;has_moretells you whether the cap hid further records. - Subscriptions (
GET /subscriptions,GET /subscriptions/{id}): active subscriptions with status, customer, period end, and items (price, amount, interval). A read before any cancellation.
Stripe amounts use minor units: ordinary zero-decimal currencies such as JPY display as whole units, while other currencies display two decimals. UGX and ISK retain two-decimal API values for backward compatibility, so an amount of 500 displays as 5.00 UGX or 5.00 ISK. JSON preserves the original integer (amount_minor, or unit_amount_minor for subscription prices) and currency next to the formatted display value. HUF and TWD use two decimals for charge/price records (their whole-unit rule applies to manual payouts). Three-decimal currencies that Stripe does not support for presentment are rejected. See references/01-stripe-read-operations.md for sources and details.
Guarded mutation: subscription cancellation
subscriptions cancel --id sub_... --dry-runpreviews the cancellation;--yesconfirms and postscancel_at_period_end=true— the safe default that schedules cancellation at the period end (customer keeps service until then) rather than canceling immediately.- The script verifies Stripe confirmed the change (response
cancel_at_period_end: true) before reporting success; a mismatch raises an error and no state change is assumed. - Cancellation scheduled at period end is reversible by setting
cancel_at_period_end=falsebefore the period ends. Immediate cancellation and refunds are deliberately NOT in this skill's mutation surface — they need a human at the Stripe dashboard or a dedicated integration.
Access model and credentials
- Stripe authenticates with secret keys (
sk_...) or restricted keys (rk_...). Use a restricted key scoped to read-only (balance:read,payment_intents:read,subscriptions:read) for the read surface; addsubscriptions:writeonly where cancellations are genuinely needed. - Keys are live or test (
sk_live_/sk_test_). Never point live keys at test data or vice versa; verify the key type before running anything that could touch real charges. - Store keys in
STRIPE_API_KEY, never in code, chat, or commits. Rotate a leaked key immediately in the Stripe dashboard.
Reference routing
| Load when | Reference |
|---|---|
| Sources, refresh procedure | references/00-source-index.md |
| Endpoints, pagination, cancellation semantics, errors | references/01-stripe-read-operations.md |
Included artifacts
scripts/stripe-cli: bounded, stdlib-only CLI (balance, payments list, subscriptions list/get, guarded cancel;--json;--limit; mutation gated by--dry-run/--yes).tests/test_stripe_cli.py: 14 deterministic tests against a stub Stripe API, including USD/JPY formatting, special currency rules, raw-unit preservation, and the mutation gate.references/: dated source index + Stripe read-operations reference.evals/evals.json: seven output-quality evaluation cases for agent runs.
Verification boundary
| Claim | Minimum evidence |
|---|---|
| Balance is current | stripe-cli balance show --json returns available and pending per currency |
| A payment succeeded | stripe-cli payments list --json shows the intent with status succeeded |
| A subscription is active | stripe-cli subscriptions get --json returns status active and period end |
| A cancellation was accepted | stripe-cli subscriptions cancel --yes exits 0 and the response has cancel_at_period_end: true |
| A mutation is safe to run | stripe-cli subscriptions cancel --dry-run prints the exact subscription ID |
Hard boundaries
- Never cancel a subscription without a human directive,
--dry-runpreview, and--yesconfirmation — cancellations have billing consequences. - The mutation surface is limited to scheduling cancellation at period end. Refunds, immediate cancellations, and charge operations are out of scope.
- Never page reads past
--limit; never dump full API keys, customer data, or raw payloads into chat. - This skill operates the Stripe API. It does not build payments into applications or cover other payment processors.
When not to use
- Building Stripe payments into an application (Checkout, Payment Intents in code, webhooks for your app, billing logic) — that is integration development; see backend-engineering.
- Stripe dashboard administration (account settings, bank accounts, disputes, tax registration) — that is the Stripe Dashboard.
- Refunds, immediate cancellations, or charge operations — deliberately out of this skill's guarded-mutation surface; those are human decisions in the dashboard or a dedicated integration.
- Other payment processors (Braintree, Adyen, PayPal) — each has its own API and tooling; this skill covers Stripe.