402 Payment Required / X-PAYMENT retries without touching Stripe
sandbox quota or real chain gas.
By use case
The twin’s surface has grown well past its original PaymentIntent-only scope, so a short bullet list can’t tell you whether your specific flow is covered. These are the use cases agents actually exercise against it, each naming the MCP tools and REST routes involved. For whether the fidelity check is currently passing and how recently it ran, see status.pome.sh.Create and settle a crypto PaymentIntent
Create a PaymentIntent, drive it throughrequires_action, and settle it with
the test-helper deposit tool. MCP: create_payment_intent,
confirm_payment_intent, retrieve_payment_intent, simulate_crypto_deposit.
REST: POST /v1/payment_intents, POST .../confirm,
POST /v1/test_helpers/payment_intents/:id/simulate_crypto_deposit.
Reconcile a refund
Issue a refund against a settled charge, then confirm it against the event log and balance. MCP:create_refund, retrieve_refund, list_refunds,
retrieve_charge, list_events, retrieve_balance. REST:
POST /v1/refunds, GET /v1/refunds/:id, GET /v1/events,
GET /v1/balance.
Manage a customer and their payment methods
Create a customer record, attach a payment method to it, and look up what’s on file before charging again. MCP:create_customer, retrieve_customer,
update_customer, delete_customer, list_customers,
create_payment_method, attach_payment_method, detach_payment_method,
list_customer_payment_methods. REST: POST/GET/DELETE /v1/customers,
GET .../customers/:id/payment_methods,
POST .../payment_methods/:id/attach.
Inspect a subscription and its billing objects
Read products, prices, subscriptions, and invoices. REST:GET/POST /v1/products, /v1/prices, /v1/subscriptions (products, prices,
and subscriptions support POST); /v1/invoices is GET-only — nothing
mints an invoice, so GET /v1/invoices always returns an empty list and
GET /v1/invoices/:id always 404s. These routes are shape-tier, not
semantic — there’s no billing engine behind them running actual
billing-cycle math, so responses match Stripe’s shape but the numbers inside
aren’t computed the way real Stripe computes them. Don’t build a task that
asserts on invoice amounts, invoice creation, or subscription period math
yet.
Gate a resource behind x402
Protect a route withpaymentMiddleware(), return a 402 challenge, and
accept a retried request carrying an X-PAYMENT header once the agent pays.
Simulate failures for idempotency testing
Inject a lost-response failure on a refund or PaymentIntent call and confirm the agent retries with the same idempotency key instead of double-charging.What’s out of scope
Checkout, Connect, webhook delivery loops, and most of the full Stripe surface beyond what’s listed above. Unsupported routes return 501 withfidelity: "unsupported".
Fidelity
Every surface above is tiered — semantic (a full behavioral contract, checked by an automated weekly capture), shape (the response shape matches but values aren’t asserted, as with the billing objects above), or unsupported (a loud 501 instead of a faked success). Only part of the semantic surface is captured by the weekly check today; the rest is rolling out. The Stripe row on status.pome.sh shows whether the check is passing and how recently it last ran — it does not list individual surfaces, so check the tiers above before you rely on a specific tool or route in a task.Quickstart
## Seed State block, hands your agent a session URL and token, and scores the
run when the agent exits.
Point your agent at it
During a localpome run, Pome injects these environment variables into the agent
process:
POME_STRIPE_API_BASE and POME_STRIPE_API_KEY.
It also accepts Stripe-style API keys. Tasks seed a default test key:
Authorization: Bearer <token> — both resolve to the same session.
POME_STRIPE_REST_URL.
To check whether the twin process is alive during a run:
Stripe also runs standalone via
pome twin start stripe, in-process via pome run,
or through pome session create --twin stripe on hosted.Task seed shape
Stripe tasks use a flat seed block withapi_keys, and optionally
payment_intents, charges, refunds, and failure_injection rules:
twins: ["stripe"] in the task’s ## Config block.