ChatGPT 订阅 GoPay支付出错的解决办法

跟着佬友的喂饭教程操作 https://linux.do/t/topic/2089572/1 在 ChatGPT 订阅页面使用 GoPay 支付时,遇到提示“出错了,请重试”的问题。 除了换邮箱换节点,还有一个更简单的方法,就是跳转到Stripe长链接支付 用codex写了一个油猴脚本,可以在订阅界...
ChatGPT 订阅 GoPay支付出错的解决办法
ChatGPT 订阅 GoPay支付出错的解决办法

跟着佬友的喂饭教程操作 https://linux.do/t/topic/2089572/1
在 ChatGPT 订阅页面使用 GoPay 支付时,遇到提示“出错了,请重试”的问题。

1

除了换邮箱换节点,还有一个更简单的方法,就是跳转到Stripe长链接支付 :grinning_face:

用codex写了一个油猴脚本,可以在订阅界面点GoPay支付按钮自动跳转

1 2

3
4

// ==UserScript==
// @name         ChatGPT GoPay 跳转
// @namespace    https://chatgpt.com/
// @author       Miku-Y
// @version      1.5.0
// @description  在 ChatGPT checkout 页面显示 GoPay 按钮,用户点击后生成 Stripe hosted checkout 长链接并跳转
// @match        https://chatgpt.com/*
// @run-at       document-start
// @grant        none
// ==/UserScript==

(() => {
    "use strict";

    const PATH = "/checkout/openai_llc/";
    const BTN_ID = "gopay-checkout-button";
    const TIP_ID = "gopay-checkout-tip";
    const BTN_CSS = "position:fixed;left:16px;top:50%;transform:translateY(-50%);z-index:2147483647;height:46px;min-width:136px;border:0;border-radius:8px;background:#10a37f;color:#fff;font:700 16px/1 -apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;box-shadow:0 10px 28px rgba(16,163,127,.34);cursor:pointer";
    const TIP_CSS = "position:fixed;left:16px;top:calc(50% + 34px);z-index:2147483647;max-width:360px;padding:12px 14px;border-radius:8px;font:14px/1.5 -apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;box-shadow:0 8px 28px rgba(0,0,0,.18);color:#fff";
    const PAYLOAD = {
        plan_name: "chatgptplusplan",
        billing_details: { country: "ID", currency: "IDR" },
        cancel_url: "https://chatgpt.com/#pricing",
        promo_campaign: { promo_campaign_id: "plus-1-month-free", is_coupon_from_query_param: false },
        checkout_ui_mode: "hosted",
    };
    let timer = null;
    let busy = false;

    const $ = (id) => document.getElementById(id);
    const inCheckout = () => location.pathname.startsWith(PATH);
    const mount = (el) => (document.body || document.documentElement).appendChild(el);

    function tip(text, error = false) {
        let el = $(TIP_ID);
        if (!el) {
            el = document.createElement("div");
            el.id = TIP_ID;
            el.style.cssText = TIP_CSS;
            mount(el);
        }
        el.textContent = text;
        el.style.background = error ? "#991b1b" : "#111827";
    }

    function setLoading(button, loading) {
        button.disabled = loading;
        button.textContent = loading ? "跳转中,请等待..." : "GoPay支付";
        button.style.opacity = loading ? ".72" : "1";
        button.style.cursor = loading ? "wait" : "pointer";
    }

    async function fetchJson(url, options) {
        const response = await fetch(url, options);
        const data = await response.json().catch(() => null);
        if (!response.ok) throw Object.assign(new Error(`HTTP ${response.status}`), { data });
        return data;
    }

    async function pay(button) {
        if (busy) return;
        busy = true;
        setLoading(button, true);
        tip("正在生成 Stripe 付款链接...");

        try {
            const token = (await fetchJson("/api/auth/session", { credentials: "include" }))?.accessToken;
            if (!token) throw new Error("获取登录 Token 失败,请确认 ChatGPT 已登录");

            const data = await fetchJson("https://chatgpt.com/backend-api/payments/checkout", {
                method: "POST",
                credentials: "include",
                headers: {
                    Authorization: `Bearer ${token}`,
                    "Content-Type": "application/json",
                },
                body: JSON.stringify(PAYLOAD),
            });
            const hostedUrl = data?.url || data?.stripe_hosted_url || data?.checkout_url;
            if (!hostedUrl) throw new Error("未找到 Stripe 长链接,请看控制台原始响应");

            console.log("[plus-link] Stripe 长链接:", hostedUrl, data);
            tip("Stripe 链接生成成功,正在跳转...");
            location.assign(hostedUrl);
        } catch (error) {
            console.error("[plus-link]", error);
            busy = false;
            setLoading(button, false);
            tip(error.message || "请求失败,请看控制台日志", true);
        }
    }

    function showButton() {
        if (!inCheckout() || $(BTN_ID)) return;
        const button = document.createElement("button");
        button.id = BTN_ID;
        button.type = "button";
        button.textContent = "GoPay支付";
        button.style.cssText = BTN_CSS;
        button.addEventListener("click", () => pay(button));
        mount(button);
    }

    function sync() {
        if (!inCheckout()) {
            clearTimeout(timer);
            timer = null;
            $(BTN_ID)?.remove();
            $(TIP_ID)?.remove();
            return;
        }
        if (!$(BTN_ID) && !timer) {
            timer = setTimeout(() => {
                timer = null;
                showButton();
            }, 3000);
        }
    }

    for (const method of ["pushState", "replaceState"]) {
        const raw = history[method];
        history[method] = function (...args) {
            const result = raw.apply(this, args);
            setTimeout(sync, 50);
            return result;
        };
    }

    window.addEventListener("popstate", () => setTimeout(sync, 50));
    window.addEventListener("DOMContentLoaded", sync);
    sync();
    setTimeout(sync, 1000);
})();

4 个帖子 - 3 位参与者

阅读完整话题

来源: linux.do查看原文