Skip to content

Instantly share code, notes, and snippets.

@thuongtin
Last active June 30, 2026 04:47
Show Gist options
  • Select an option

  • Save thuongtin/8d30df225f73f0cd103c5cda2eee021c to your computer and use it in GitHub Desktop.

Select an option

Save thuongtin/8d30df225f73f0cd103c5cda2eee021c to your computer and use it in GitHub Desktop.
(async function generateTeamLink() {
// ============================================================
// CẤU HÌNH (có thể chỉnh tay khi cần)
// ============================================================
const CONFIG = {
workspaceName: "workspace", // Tên workspace
priceInterval: "month", // "month" hoặc "year"
seatQuantity: 2, // Số ghế (Team tối thiểu 2)
// Ép thủ công nếu không muốn tự nhận biết. Để null = tự động.
forceCurrency: null, // ví dụ "AUD"
forceCountry: null, // ví dụ "AU"
// Selector block giá trong pricing modal (chứa dòng "USD per seat...").
// Để null sẽ tự quét toàn trang.
currencySelector: '[data-testid="team-pricing-column-cost"]'
};
// ============================================================
// BẢNG QUY ĐỔI: TIỀN TỆ -> MÃ QUỐC GIA
// (EUR mặc định "IE" vì dùng chung nhiều nước — đổi forceCountry nếu cần)
// ============================================================
const CURRENCY_TO_COUNTRY = {
USD: "US", AUD: "AU", GBP: "GB", EUR: "IE", CAD: "CA",
NZD: "NZ", JPY: "JP", CNY: "CN", HKD: "HK", SGD: "SG",
INR: "IN", BRL: "BR", MXN: "MX", CHF: "CH", SEK: "SE",
NOK: "NO", DKK: "DK", PLN: "PL", ZAR: "ZA", AED: "AE",
SAR: "SA", TRY: "TR", KRW: "KR", THB: "TH", IDR: "ID",
MYR: "MY", PHP: "PH", VND: "VN", TWD: "TW", ILS: "IL"
};
// ============================================================
// BẢNG KÝ HIỆU -> TIỀN TỆ (thứ tự quan trọng: cụ thể trước, "$" chung sau cùng)
// ============================================================
const SYMBOL_TO_CURRENCY = [
{ re: /A\$/, cur: "AUD" },
{ re: /US\$/, cur: "USD" },
{ re: /C\$|CA\$/, cur: "CAD" },
{ re: /NZ\$/, cur: "NZD" },
{ re: /HK\$/, cur: "HKD" },
{ re: /S\$/, cur: "SGD" },
{ re: /R\$/, cur: "BRL" },
{ re: /£/, cur: "GBP" },
{ re: /€/, cur: "EUR" },
{ re: /₩/, cur: "KRW" },
{ re: /₫/, cur: "VND" },
{ re: /₹/, cur: "INR" },
{ re: /¥/, cur: "JPY" }, // mặc định JPY (¥ có thể là CNY)
{ re: /\$/, cur: "USD" } // fallback chung cho "$"
];
// Quét mã ISO trực tiếp trên trang (ưu tiên cao nhất)
const ISO_RE = /\b(USD|AUD|GBP|EUR|CAD|NZD|JPY|CNY|HKD|SGD|INR|BRL|MXN|CHF|SEK|NOK|DKK|PLN|ZAR|AED|SAR|TRY|KRW|THB|IDR|MYR|PHP|VND|TWD|ILS)\b/;
// ---- Lấy mã giảm giá từ URL hiện tại (?promoCode=...) ----
function getCouponFromURL() {
try {
return new URL(location.href).searchParams.get("promoCode") || null;
} catch {
return null;
}
}
// ---- Tự nhận biết tiền tệ từ trang ----
function detectCurrency() {
if (CONFIG.forceCurrency) return CONFIG.forceCurrency;
let text = "";
if (CONFIG.currencySelector) {
const el = document.querySelector(CONFIG.currencySelector);
text = el ? el.textContent : "";
}
if (!text) text = document.body ? document.body.innerText : "";
// 1) Ưu tiên mã ISO (USD, AUD, ...)
const iso = text.match(ISO_RE);
if (iso) return iso[1];
// 2) Rồi tới ký hiệu tiền tệ
for (const { re, cur } of SYMBOL_TO_CURRENCY) {
if (re.test(text)) return cur;
}
return null;
}
// ============================================================
// BẮT ĐẦU
// ============================================================
console.log("⏳ Đang lấy Session Token...");
let accessToken;
try {
const s = await fetch("/api/auth/session").then(r => r.json());
accessToken = s?.accessToken;
if (!accessToken) throw new Error("accessToken rỗng");
} catch (e) {
console.error("❌ Lấy Token thất bại:", e.message);
return;
}
console.log("✅ Lấy Token thành công");
// ---- Mã giảm giá ----
const coupon = getCouponFromURL();
if (coupon) {
console.log("🎟️ Mã giảm giá (lấy từ URL):", coupon);
} else {
console.warn("⚠️ Không thấy promoCode trên URL. Hãy mở trang dạng https://chatgpt.com/?promoCode=XXXX");
}
// ---- Tiền tệ + quốc gia ----
const currency = detectCurrency();
if (!currency) {
console.error("❌ Không nhận biết được tiền tệ. Hãy đặt CONFIG.forceCurrency hoặc CONFIG.currencySelector.");
return;
}
const country = CONFIG.forceCountry || CURRENCY_TO_COUNTRY[currency];
if (!country) {
console.error(`❌ Chưa có mã quốc gia cho tiền tệ ${currency}. Bổ sung vào CURRENCY_TO_COUNTRY hoặc đặt CONFIG.forceCountry.`);
return;
}
console.log(`🌐 Nhận biết: tiền tệ ${currency} → quốc gia ${country}`);
// ---- Payload ----
const payload = {
plan_name: "chatgptteamplan",
team_plan_data: {
workspace_name: CONFIG.workspaceName,
price_interval: CONFIG.priceInterval,
seat_quantity: CONFIG.seatQuantity
},
billing_details: { country, currency },
cancel_url: coupon ? `https://chatgpt.com/?promoCode=${coupon}` : "https://chatgpt.com/",
promo_code: coupon || undefined, // bỏ qua nếu không có
checkout_ui_mode: "hosted"
};
console.log(`⏳ Đang yêu cầu link Stripe (${country}/${currency})...`);
try {
const resp = await fetch(
"https://chatgpt.com/backend-api/payments/checkout",
{
method: "POST",
headers: {
Authorization: `Bearer ${accessToken}`,
"Content-Type": "application/json"
},
body: JSON.stringify(payload)
}
);
const data = await resp.json();
if (!resp.ok) {
console.error(`❌ Yêu cầu thất bại HTTP ${resp.status}`);
console.log("📋 Chi tiết phản hồi:", data);
return;
}
const hostedUrl = data?.url || data?.stripe_hosted_url || data?.checkout_url;
if (!hostedUrl) {
console.warn("⚠️ Không tìm thấy link, phản hồi gốc:", data);
return;
}
console.log("─".repeat(60));
console.log("✅ Tạo link ChatGPT Team thành công!");
console.log("📋 Checkout Session ID :", data.checkout_session_id);
console.log(`📌 Gói : ChatGPT Team (${country}/${currency})`);
console.log("💺 Số ghế :", payload.team_plan_data.seat_quantity);
console.log("🎟️ Mã giảm giá :", coupon || "(không có)");
console.log("🔗 Link Stripe:");
console.log(hostedUrl);
console.log("─".repeat(60));
} catch (e) {
console.error("❌ Lỗi mạng:", e.message);
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment