stripe-create-subscription

code_execution · unverified · null · json · download .py

Stripe Price ID to subscribe to (price_...)

import sys
import os
import subprocess
import time
import urllib.request
import json

# ─────────────────────────────────────────
# PRE_EXECUTION
# ─────────────────────────────────────────

for attempt in range(2):
    try:
        req = urllib.request.Request(
            "https://checklist.day/api/registry/stripe",
            headers={"User-Agent": "checklist-agent/1.0"}
        )
        with urllib.request.urlopen(req, timeout=10) as resp:
            registry = json.loads(resp.read())
            break
    except Exception as e:
        if attempt == 1:
            print(f"ABORT: registry unreachable — {e}")
            sys.exit(1)
        time.sleep(2)

warnings = registry.get("warnings", [])
if warnings:
    print("[stripe] WARNINGS:")
    for w in warnings if isinstance(warnings, list) else [warnings]:
        print(f"  ⚠ {w}")

# ─────────────────────────────────────────
# EXECUTION
# ─────────────────────────────────────────

subprocess.check_call([sys.executable, "-m", "pip", "install", "-q", "stripe>=7.0.0"])

import stripe

STRIPE_SECRET_KEY = os.environ.get("STRIPE_SECRET_KEY")
STRIPE_PRICE_ID   = os.environ.get("STRIPE_PRICE_ID")

if not STRIPE_SECRET_KEY:
    print("ABORT: STRIPE_SECRET_KEY not set"); sys.exit(1)
if not STRIPE_SECRET_KEY.startswith("sk_test_"):
    print("ABORT: use test mode key (sk_test_...)"); sys.exit(1)
if not STRIPE_PRICE_ID:
    print("ABORT: STRIPE_PRICE_ID not set (price_...)"); sys.exit(1)

stripe.api_key = STRIPE_SECRET_KEY

# Create test customer with payment method
customer = stripe.Customer.create(
    email="checklist-sub-test@example.com",
    payment_method="pm_card_visa",
    invoice_settings={"default_payment_method": "pm_card_visa"},
)
customer_id = customer.id
print(f"  customer: {customer_id}")

subscription_id = None
invoice_id      = None

try:
    # FOOTGUN: payment_behavior=default_incomplete required for SCA — don't use error_if_incomplete
    subscription = stripe.Subscription.create(
        customer=customer_id,
        items=[{"price": STRIPE_PRICE_ID}],
        payment_behavior="default_incomplete",
        expand=["latest_invoice.payment_intent"],
        idempotency_key=f"checklist-sub-{int(time.time())}",
    )

    subscription_id = subscription.id
    status          = subscription.status
    invoice_id      = subscription.latest_invoice.id if subscription.latest_invoice else None

    print(f"  subscription: {subscription_id} (status={status})")
    print(f"  invoice: {invoice_id}")

    # Cleanup
    stripe.Subscription.cancel(subscription_id)
    print(f"  cancelled: {subscription_id}")

finally:
    stripe.Customer.delete(customer_id)
    print(f"  deleted customer: {customer_id}")

# ─────────────────────────────────────────
# POST_EXECUTION
# ─────────────────────────────────────────

assert subscription_id and subscription_id.startswith("sub_"), f"FAIL: invalid subscription ID {subscription_id}"
assert status in ("incomplete", "active", "trialing"), f"FAIL: unexpected status '{status}'"

result = {
    "subscription_id": subscription_id,
    "status":          status,
    "customer_id":     customer_id,
    "invoice_id":      invoice_id,
}
print(json.dumps(result, indent=2))
print("PASS")