{"id":"stripe-issue-refund","version":"1.0.0","primitive":"code_execution","description":"Stripe secret key (sk_test_... for test mode)","registry_refs":["stripe"],"tags":[],"solves":[],"auth_required":true,"verified":false,"last_verified":"null","next_check":"2026-07-30","eval_result":"null","eval_env":"null","mast":[],"ref":"https://arxiv.org/abs/2503.13657","inputs":[{"name":"STRIPE_SECRET_KEY","required":true,"description":"Stripe secret key (sk_test_... for test mode)"}],"executable":"# ============================================\n# checklist:     stripe-issue-refund\n# version:       1.0.0\n# primitive:     code_execution\n# description:   Issue a full or partial refund on a Stripe PaymentIntent and verify refund status\n# registry_refs: stripe\n# auth_required: true\n# verified:      false\n# last_verified: null\n# next_check:    2026-07-30\n# eval_result:   null\n# eval_env:      null\n#\n# inputs:\n#   - name: STRIPE_SECRET_KEY\n#     required: true\n#     description: Stripe secret key (sk_test_... for test mode)\n#\n# OUTPUTS:\n#   refund_id       — Stripe refund ID (re_...)\n#   refund_status   — refund status (succeeded)\n#   amount_refunded — amount refunded in cents\n#   partial_ok      — true if partial refund worked correctly\n#\n# MAST FAILURE MODES ADDRESSED:\n# FM-1.1 Disobey Task Specification        — refund via charge or payment_intent (both shown)\n# FM-3.3 Incorrect Verification            — refund status verified, not just creation\n#\n# ref: https://arxiv.org/abs/2503.13657\n# ============================================\n\nimport sys\nimport os\nimport subprocess\nimport time\nimport urllib.request\nimport json\n\n# ─────────────────────────────────────────\n# PRE_EXECUTION\n# ─────────────────────────────────────────\n\nfor attempt in range(2):\n    try:\n        req = urllib.request.Request(\n            \"https://checklist.day/api/registry/stripe\",\n            headers={\"User-Agent\": \"checklist-agent/1.0\"}\n        )\n        with urllib.request.urlopen(req, timeout=10) as resp:\n            registry = json.loads(resp.read())\n            break\n    except Exception as e:\n        if attempt == 1:\n            print(f\"ABORT: registry unreachable — {e}\")\n            sys.exit(1)\n        time.sleep(2)\n\nwarnings = registry.get(\"warnings\", [])\nif warnings:\n    print(\"[stripe] WARNINGS:\")\n    for w in warnings if isinstance(warnings, list) else [warnings]:\n        print(f\"  ⚠ {w}\")\n\n# ─────────────────────────────────────────\n# EXECUTION\n# ─────────────────────────────────────────\n\nsubprocess.check_call([sys.executable, \"-m\", \"pip\", \"install\", \"-q\", \"stripe>=7.0.0\"])\n\nimport stripe\n\nSTRIPE_SECRET_KEY = os.environ.get(\"STRIPE_SECRET_KEY\")\nif not STRIPE_SECRET_KEY:\n    print(\"ABORT: STRIPE_SECRET_KEY not set\"); sys.exit(1)\nif not STRIPE_SECRET_KEY.startswith(\"sk_test_\"):\n    print(\"ABORT: use test mode key\"); sys.exit(1)\n\nstripe.api_key = STRIPE_SECRET_KEY\n\nAMOUNT_CENTS   = 3000\nPARTIAL_REFUND = 1000\n\n# Create and confirm a payment to refund\nintent = stripe.PaymentIntent.create(\n    amount=AMOUNT_CENTS,\n    currency=\"usd\",\n    payment_method=\"pm_card_visa\",\n    payment_method_types=[\"card\"],\n    confirm=True,\n    return_url=\"https://checklist.day\",\n    idempotency_key=f\"checklist-refund-pi-{int(time.time())}\",\n)\npayment_intent_id = intent.id\nprint(f\"  payment: {payment_intent_id} (status={intent.status})\")\n\n# Full refund\n# FOOTGUN: refund via payment_intent — not charge ID (charge deprecated as primary key)\nrefund = stripe.Refund.create(\n    payment_intent=payment_intent_id,\n    idempotency_key=f\"checklist-refund-{int(time.time())}\",\n)\nrefund_id      = refund.id\nrefund_status  = refund.status\namount_refunded = refund.amount\nprint(f\"  full refund: {refund_id} status={refund_status} amount={amount_refunded}\")\n\n# Partial refund test — create new payment\nintent2 = stripe.PaymentIntent.create(\n    amount=AMOUNT_CENTS,\n    currency=\"usd\",\n    payment_method=\"pm_card_visa\",\n    payment_method_types=[\"card\"],\n    confirm=True,\n    return_url=\"https://checklist.day\",\n    idempotency_key=f\"checklist-refund2-pi-{int(time.time())}\",\n)\npartial_refund_obj = stripe.Refund.create(\n    payment_intent=intent2.id,\n    amount=PARTIAL_REFUND,\n)\npartial_ok = partial_refund_obj.amount == PARTIAL_REFUND and partial_refund_obj.status == \"succeeded\"\nprint(f\"  partial refund: {partial_refund_obj.amount} cents status={partial_refund_obj.status} ok={partial_ok}\")\n\n# ─────────────────────────────────────────\n# POST_EXECUTION\n# ─────────────────────────────────────────\n\nassert refund_id.startswith(\"re_\"), f\"FAIL: expected re_... ID, got {refund_id}\"\nassert refund_status == \"succeeded\", f\"FAIL: refund status '{refund_status}'\"\nassert amount_refunded == AMOUNT_CENTS, f\"FAIL: expected {AMOUNT_CENTS}, got {amount_refunded}\"\nassert partial_ok, \"FAIL: partial refund failed\"\n\nresult = {\n    \"refund_id\":       refund_id,\n    \"refund_status\":   refund_status,\n    \"amount_refunded\": amount_refunded,\n    \"partial_ok\":      partial_ok,\n}\nprint(json.dumps(result, indent=2))\nprint(\"PASS\")\n"}