• 喜欢玩小鸡

    有些人可能会疑问这个通用码是不是必须要是对应地区的节点才能搞啊?其实并不是,先分清两个概念,一个是 ip 所对应的区域,另一个是你想要结算的货币。提长链的时候要注意 ip 所对应的区域要一致,然后货币选对了那么就是你想要的价格,比如想用新加坡 ip 选择埃及,那么区域改成 SG,货币改成 EGP 就好了

    具体怎么做呢?首先搞清楚你现在的节点的 ip 所对应的国家,假设是 SG,然后我想要付埃及的 1150 EGP,那么把脚本里面对应的 IP_REGION 改成 SG,CURRENCY_REGION 改成 EGP 就好```
    (async function generateAUTeamLink() {
    // ================= 配置项 =================
    const COUPON = "XXXXXXXXXXXX"; // 优惠码,替换自己的通用码
    const IP_REGION = "SG"; // 你的节点出口 IP 对应的国家
    const CURRENCY_REGION = "EGP"; // 你想要结算的货币种类
    const WORKSPACE_NAME = "xxx";
    const EXISTING_WORKSPACE_ID = "";
    const SEAT_QUANTITY = 2;
    const AUTO_OPEN_CHECKOUT = false;

    // ==========================================

    if (window.location.origin !== "https://chatgpt.com") {
    throw new Error(请在 https://chatgpt.com 页面执行脚本,当前来源为 ${window.location.origin});
    }

    console.log("⏳ 正在获取 ChatGPT Session Token...");

    // 1. 自动获取登录凭证
    let accessToken;
    try {
    const s = await fetch("/api/auth/session", { credentials: "include" }).then(r => r.json());
    accessToken = s?.accessToken;
    if (!accessToken) throw new Error("accessToken 为空,请确认已登录 ChatGPT 账号");
    const currentAccount = s.account || {};
    const currentPlan = currentAccount.planType || currentAccount.plan_type;
    const currentStructure = currentAccount.structure;
    if (currentPlan !== "free" || currentStructure !== "personal") {
    throw new Error("当前选中的不是 Personal/Free 个人账户,请先切换个人账户后重试");
    }
    } catch (e) {
    console.error("❌ 获取 Token 失败:", e.message);
    return;
    }
    console.log("✅ Token 获取成功");

    // 2. 构建请求 Payload
    const payload = {
    plan_name: "chatgptteamplan",
    team_plan_data: {
    workspace_name: WORKSPACE_NAME,
    price_interval: "month", // month 或 year
    seat_quantity: SEAT_QUANTITY,
    ...(EXISTING_WORKSPACE_ID ? { existing_workspace_id: EXISTING_WORKSPACE_ID } : {})
    },
    billing_details: {
    country: IP_REGION,
    currency: CURRENCY_REGION
    },
    cancel_url: "https://chatgpt.com/?promoCode=" + COUPON,
    promo_code: COUPON,
    checkout_ui_mode: "hosted"
    };

    // 3. 请求 Stripe 长链接
    console.log("⏳ 正在请求 Stripe 支付长链接...");
    try {
    const resp = await fetch(
    "/backend-api/payments/checkout",
    {
    method: "POST",
    headers: {
    Authorization: Bearer ${accessToken},
    "Content-Type": "application/json"
    },
    credentials: "same-origin",
    body: JSON.stringify(payload)
    }
    );
    const data = await resp.json();

    if (!resp.ok) {
    console.error(❌ 请求失败 HTTP ${resp.status});
    console.log("📋 响应详情:", data);
    return;
    }

    const hostedUrl = data?.url || data?.stripe_hosted_url || data?.checkout_url;
    if (!hostedUrl) {
    console.warn("⚠️ 未找到长链接,原始响应:", data);
    return;
    }
    const checkoutUrl = new URL(hostedUrl);
    if (checkoutUrl.protocol !== "https:") {
    throw new Error("服务端返回了无效的支付链接");
    }

    // 4. 打印结果
    console.log("─".repeat(60));
    console.log("✅ ChatGPT Team 链接生成成功!");
    console.log(📌 工作区名称 : ${payload.team_plan_data.workspace_name});
    console.log(💺 席位数量 : ${payload.team_plan_data.seat_quantity});
    console.log(🎟️ 优惠码 : ${COUPON});
    console.log(🌍 地区/货币 : ${payload.billing_details.country} (${payload.billing_details.currency}));
    if (data.checkout_session_id) {
    console.log(🆔 Session ID : ${data.checkout_session_id});
    }
    console.log("─".repeat(60));
    console.log("🔗 Stripe 支付长链接(复制到浏览器打开):");
    console.log(checkoutUrl.href);
    console.log("─".repeat(60));
    if (AUTO_OPEN_CHECKOUT) {
    window.open(checkoutUrl.href, "_blank", "noopener,noreferrer");
    }
    } catch (e) {
    console.error("❌ 网络异常或请求失败:", e.message);
    }
    })();

    主楼
  • leepsmarts

    b d

    #1
  • vweio2

发表回复

登录后回复