用法:
打开 Tampermonkey 新建脚本。
粘贴这个文件内容保存。
访问:
https://chatgpt.com/codex/team/checkout?checkout_from=codex_app
页面右下角会出现按钮:
执行 checkout/update quantity=13
等页面出现有效 checkout_session_id 后点按钮。
注意:如果右下角显示:
当前 checkout_session_id: (未检测到,等页面跳转后再点)
说明当前 URL 还是 /checkout?..,还没拿到真正的 checkout session id,不能点。
// ==UserScript==
// @name CTF Codex Checkout Update Helper
// @namespace ctf-sandbox
// @version 0.1.0
// @description Run the Codex checkout/update request from the logged-in browser page context.
// @match https://chatgpt.com/codex/team/checkout*
// @match https://chatgpt.com/codex/team/checkout/*
// @run-at document-idle
// @grant none
// ==/UserScript==
(() => {
‘use strict’;
const CONFIG = {
processor_entity: ‘openai_llc’,
credit_purchase_quantity: 13,
language: ‘zh-CN’,
updateUrl: ‘https://chatgpt.com/backend-api/payments/checkout/update’,
};
function log(…args) {
console.log(‘[CTF checkout helper]’, …args);
}
function getCheckoutSessionId() {
const url = new URL(window.location.href);
const fromQuery = url.searchParams.get(‘checkout_session_id’) || url.searchParams.get(‘checkoutSessionId’);
const parts = url.pathname.split(‘/’).filter(Boolean);
const fromPath = parts[parts.length - 1] || ‘’;
const id = fromQuery || fromPath;
// The entry URL ends in /checkout. That is not a real checkout_session_id.
if (!id || id === 'checkout' || id === 'team' || id === 'codex') return '';
return id;
}
async function getAccessToken() {
const sessionRes = await fetch(‘/api/auth/session’, { credentials: ‘include’ });
if (!sessionRes.ok) {
const text = await sessionRes.text().catch(() => ‘’);
throw new Error(获取 session 失败 (HTTP ${sessionRes.status}): ${text.slice(0, 120)});
}
const sessionData = await sessionRes.json();
const accessToken = sessionData?.accessToken;
if (!accessToken) throw new Error(‘未找到 accessToken,请确认已登录’);
return accessToken;
}
async function runUpdate() {
const checkoutSessionId = getCheckoutSessionId();
if (!checkoutSessionId) {
throw new Error(当前 URL 还没有有效 checkout_session_id: ${window.location.href});
}
const accessToken = await getAccessToken();
const body = {
checkout_session_id: checkoutSessionId,
processor_entity: CONFIG.processor_entity,
credit_purchase_quantity: CONFIG.credit_purchase_quantity,
};
log('request body:', body);
const res = await fetch(CONFIG.updateUrl, {
method: 'POST',
credentials: 'include',
referrer: window.location.href,
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${accessToken}`,
'oai-device-id': localStorage.getItem('oai-device-id') || '',
'oai-language': CONFIG.language,
},
body: JSON.stringify(body),
});
const text = await res.clone().text().catch(() => '');
let data = null;
try { data = text ? JSON.parse(text) : null; } catch (_) {}
if (!res.ok) {
throw new Error(`请求失败 (HTTP ${res.status}): ${text.slice(0, 200)}`);
}
return data ?? text;
}
function installButton() {
if (document.getElementById(‘ctf-checkout-helper-btn’)) return;
const box = document.createElement('div');
box.id = 'ctf-checkout-helper-box';
box.style.cssText = [
'position:fixed',
'z-index:2147483647',
'right:16px',
'bottom:16px',
'padding:12px',
'background:#111827',
'color:#fff',
'border:1px solid #374151',
'border-radius:10px',
'font:13px -apple-system,BlinkMacSystemFont,Segoe UI,sans-serif',
'box-shadow:0 8px 24px rgba(0,0,0,.3)',
'max-width:360px',
].join(';');
const btn = document.createElement('button');
btn.id = 'ctf-checkout-helper-btn';
btn.textContent = `执行 checkout/update quantity=${CONFIG.credit_purchase_quantity}`;
btn.style.cssText = 'cursor:pointer;padding:8px 10px;border-radius:8px;border:0;background:#10a37f;color:white;font-weight:600';
const status = document.createElement('div');
status.id = 'ctf-checkout-helper-status';
status.style.cssText = 'margin-top:8px;white-space:pre-wrap;word-break:break-word;color:#d1d5db';
status.textContent = `当前 checkout_session_id: ${getCheckoutSessionId() || '(未检测到,等页面跳转后再点)'}`;
btn.addEventListener('click', async () => {
btn.disabled = true;
status.textContent = '执行中...';
try {
const data = await runUpdate();
log('成功:', data);
status.textContent = `成功:\n${JSON.stringify(data, null, 2).slice(0, 1000)}`;
setTimeout(() => window.location.reload(), 800);
} catch (err) {
console.error('[CTF checkout helper] 失败:', err);
status.textContent = `失败: ${err?.message || err}`;
} finally {
btn.disabled = false;
}
});
box.appendChild(btn);
box.appendChild(status);
document.documentElement.appendChild(box);
setInterval(() => {
status.textContent = status.textContent.startsWith('当前 checkout_session_id:')
? `当前 checkout_session_id: ${getCheckoutSessionId() || '(未检测到,等页面跳转后再点)'}`
: status.textContent;
}, 1000);
}
installButton();
log(‘loaded on’, window.location.href);
})();
1 个帖子 - 1 位参与者