import requests import json import random from dataclasses import dataclass from typing import Any def generate_device_id(): return f"{random_hex(8)}-{random_hex(4)}-{random_hex(4)}-{random_hex(4)}-{random_hex(12)}" def random_hex(length): return ''.join(random.choices('0123456789abcdef', k=length)) @dataclass(frozen=True) class CheckoutResult: ok: bool checkout_url: str | None = None error: str | None = None raw: Any | None = None def create_eu_billing_with_browser_sim(access_token: str, *, timeout: int = 30) -> CheckoutResult: """模拟浏览器请求生成欧洲账单,返回 CheckoutResult。""" device_id = generate_device_id() headers = { 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:146.0) Gecko/20100101 Firefox/146.0', 'Accept': '*/*', 'Accept-Language': 'en-US,en;q=0.5', 'Accept-Encoding': 'gzip, deflate, br', 'Referer': 'https://chatgpt.com/', 'OAI-Language': 'en-US', 'OAI-Device-Id': device_id, 'OAI-Client-Version': 'prod-04eaaa443c69cfc8b46b5d52d2b61dbceba21862', 'OAI-Client-Build-Number': '4053703', 'Authorization': f'Bearer {access_token}', 'Content-Type': 'application/json', 'Origin': 'https://chatgpt.com', 'Connection': 'keep-alive', 'Sec-Fetch-Dest': 'empty', 'Sec-Fetch-Mode': 'cors', 'Sec-Fetch-Site': 'same-origin', 'Priority': 'u=4', 'TE': 'trailers' } payload = { "plan_name": "chatgptteamplan", "team_plan_data": { "workspace_name": "Sepa", "price_interval": "month", "seat_quantity": 5 }, "billing_details": { "country": "DE", "currency": "EUR" }, "promo_campaign": { "promo_campaign_id": "team-1-month-free", "is_coupon_from_query_param": False }, "checkout_ui_mode": "redirect" } url = "https://chatgpt.com/backend-api/payments/checkout" try: response = requests.post( url, headers=headers, json=payload, timeout=timeout, allow_redirects=False ) try: result = response.json() except json.JSONDecodeError: return CheckoutResult( ok=False, error=f"响应不是 JSON(HTTP {response.status_code})", raw=response.text, ) checkout_url = result.get('url') checkout_session_id = result.get('checkout_session_id') processor_entity = result.get('processor_entity') # 如果 url 为空,手动构造 if not checkout_url and checkout_session_id: entity = processor_entity if processor_entity else "openai_llc" checkout_url = f"https://chatgpt.com/checkout/{entity}/{checkout_session_id}" if checkout_url: return CheckoutResult(ok=True, checkout_url=checkout_url, raw=result) detail = result.get('detail', result) return CheckoutResult(ok=False, error=str(detail), raw=result) except requests.RequestException as e: return CheckoutResult(ok=False, error=str(e)) if __name__ == "__main__": print("=" * 70) print("欧洲账单生成器") print("=" * 70) access_token = input("\n输入 Access Token: ").strip() if not access_token: print("[!] Access Token 不能为空!") exit(1) print("\n[*] 正在生成...\n") result = create_eu_billing_with_browser_sim(access_token) if result.ok and result.checkout_url: print(f"\n[✓] Checkout URL:") print(f" {result.checkout_url}\n") else: print(f"\n[!] 失败: {result.error}\n")