{"id":"stripe-create-customer","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-create-customer\n# version:       1.0.0\n# primitive:     code_execution\n# description:   Create a Stripe customer with metadata and retrieve it to verify idempotent creation\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#   customer_id     — Stripe customer ID (cus_...)\n#   email           — email set on customer\n#   idempotent_ok   — true if same idempotency key returned same customer\n#   cleanup_done    — true if test customer was deleted\n#\n# MAST FAILURE MODES ADDRESSED:\n# FM-1.3 Step Repetition                   — idempotency key prevents duplicate customers on retry\n# FM-3.2 No or Incomplete Verification     — customer retrieved after creation to verify fields\n# FM-3.3 Incorrect Verification            — customer ID and email verified, not just 200 status\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\nStripeError = stripe.StripeError\n\nSTRIPE_SECRET_KEY = os.environ.get(\"STRIPE_SECRET_KEY\")\nif not STRIPE_SECRET_KEY:\n    print(\"ABORT: STRIPE_SECRET_KEY not set\")\n    sys.exit(1)\n\nif not STRIPE_SECRET_KEY.startswith(\"sk_test_\"):\n    print(\"ABORT: use test mode key (sk_test_...) — never run against live keys in tests\")\n    sys.exit(1)\n\n# FOOTGUN: set api_key before any stripe calls\nstripe.api_key = STRIPE_SECRET_KEY\n\nIDEMPOTENCY_KEY = f\"checklist-create-customer-{int(time.time())}\"\nEMAIL           = \"checklist-test@example.com\"\n\n# Create customer\ncustomer = stripe.Customer.create(\n    email=EMAIL,\n    name=\"Checklist Test User\",\n    metadata={\"source\": \"checklist.day\", \"env\": \"test\"},\n    idempotency_key=IDEMPOTENCY_KEY,\n)\ncustomer_id = customer.id\nprint(f\"  created: {customer_id} ({EMAIL})\")\n\n# Verify by retrieval\nretrieved = stripe.Customer.retrieve(customer_id)\nemail_ok  = retrieved.email == EMAIL\nprint(f\"  retrieved: email={retrieved.email} (match={email_ok})\")\n\n# Idempotency — same key returns same customer\ncustomer2    = stripe.Customer.create(\n    email=EMAIL,\n    name=\"Checklist Test User\",\n    metadata={\"source\": \"checklist.day\", \"env\": \"test\"},\n    idempotency_key=IDEMPOTENCY_KEY,\n)\nidempotent_ok = customer2.id == customer_id\nprint(f\"  idempotency: same id={idempotent_ok}\")\n\n# Cleanup\nstripe.Customer.delete(customer_id)\ncleanup_done = True\nprint(f\"  deleted: {customer_id}\")\n\n# ─────────────────────────────────────────\n# POST_EXECUTION\n# ─────────────────────────────────────────\n\nassert customer_id.startswith(\"cus_\"), f\"FAIL: expected cus_... ID, got {customer_id}\"\nassert email_ok, f\"FAIL: email mismatch on retrieval\"\nassert idempotent_ok, \"FAIL: idempotency key returned different customer\"\n\nresult = {\n    \"customer_id\":   customer_id,\n    \"email\":         EMAIL,\n    \"idempotent_ok\": idempotent_ok,\n    \"cleanup_done\":  cleanup_done,\n}\nprint(json.dumps(result, indent=2))\nprint(\"PASS\")\n"}