fix(console): stop Black subscription renewals (#51884)

This commit is contained in:
vprdev
2026-09-28 08:44:42 -07:00
committed by GitHub
parent 3c893f0a16
commit 75e1e7ae31
21 changed files with 32 additions and 83 deletions
+1 -2
View File
@@ -653,7 +653,6 @@ export const dict = {
"workspace.payments.type.subscription": "اشتراك",
"workspace.payments.view": "عرض",
"workspace.black.loading": "جارٍ التحميل...",
"workspace.black.time.day": "يوم",
"workspace.black.time.days": "أيام",
"workspace.black.time.hour": "ساعة",
@@ -663,7 +662,7 @@ export const dict = {
"workspace.black.time.fewSeconds": "بضع ثوان",
"workspace.black.subscription.title": "الاشتراك",
"workspace.black.subscription.message": "أنت مشترك في OpenCode Black مقابل ${{plan}} شهريًا.",
"workspace.black.subscription.manage": "إدارة الاشتراك",
"workspace.black.subscription.ending": "ينتهي OpenCode Black بنهاية فترة الفوترة الحالية ولن يتم تجديده. سننقلك إلى وحدة التحكم الجديدة.",
"workspace.black.subscription.rollingUsage": "استخدام لمدة 5 ساعات",
"workspace.black.subscription.weeklyUsage": "الاستخدام الأسبوعي",
"workspace.black.subscription.resetsIn": "إعادة تعيين في",
+1 -2
View File
@@ -664,7 +664,6 @@ export const dict = {
"workspace.payments.type.subscription": "assinatura",
"workspace.payments.view": "Ver",
"workspace.black.loading": "Carregando...",
"workspace.black.time.day": "dia",
"workspace.black.time.days": "dias",
"workspace.black.time.hour": "hora",
@@ -674,7 +673,7 @@ export const dict = {
"workspace.black.time.fewSeconds": "alguns segundos",
"workspace.black.subscription.title": "Assinatura",
"workspace.black.subscription.message": "Você assina o OpenCode Black por ${{plan}} por mês.",
"workspace.black.subscription.manage": "Gerenciar Assinatura",
"workspace.black.subscription.ending": "O OpenCode Black termina com o seu período de cobrança atual e não será renovado. Vamos migrar você para o novo console.",
"workspace.black.subscription.rollingUsage": "Uso de 5 horas",
"workspace.black.subscription.weeklyUsage": "Uso Semanal",
"workspace.black.subscription.resetsIn": "Reinicia em",
+1 -2
View File
@@ -660,7 +660,6 @@ export const dict = {
"workspace.payments.type.subscription": "abonnement",
"workspace.payments.view": "Vis",
"workspace.black.loading": "Indlæser...",
"workspace.black.time.day": "dag",
"workspace.black.time.days": "dage",
"workspace.black.time.hour": "time",
@@ -670,7 +669,7 @@ export const dict = {
"workspace.black.time.fewSeconds": "et par sekunder",
"workspace.black.subscription.title": "Abonnement",
"workspace.black.subscription.message": "Du abonnerer på OpenCode Black for ${{plan}} om måneden.",
"workspace.black.subscription.manage": "Administrer abonnement",
"workspace.black.subscription.ending": "OpenCode Black slutter med din nuværende faktureringsperiode og fornyes ikke. Vi flytter dig til den nye konsol.",
"workspace.black.subscription.rollingUsage": "5-timers brug",
"workspace.black.subscription.weeklyUsage": "Ugentlig brug",
"workspace.black.subscription.resetsIn": "Nulstiller i",
+1 -2
View File
@@ -662,7 +662,6 @@ export const dict = {
"workspace.payments.type.subscription": "Abonnement",
"workspace.payments.view": "Ansehen",
"workspace.black.loading": "Lade...",
"workspace.black.time.day": "Tag",
"workspace.black.time.days": "Tage",
"workspace.black.time.hour": "Stunde",
@@ -672,7 +671,7 @@ export const dict = {
"workspace.black.time.fewSeconds": "einige Sekunden",
"workspace.black.subscription.title": "Abonnement",
"workspace.black.subscription.message": "Du hast OpenCode Black für ${{plan}} pro Monat abonniert.",
"workspace.black.subscription.manage": "Abo verwalten",
"workspace.black.subscription.ending": "OpenCode Black endet mit deinem aktuellen Abrechnungszeitraum und wird nicht verlängert. Wir ziehen dich in die neue Konsole um.",
"workspace.black.subscription.rollingUsage": "5-Stunden-Nutzung",
"workspace.black.subscription.weeklyUsage": "Wöchentliche Nutzung",
"workspace.black.subscription.resetsIn": "Setzt zurück in",
+1 -2
View File
@@ -659,7 +659,6 @@ export const dict = {
"workspace.payments.type.subscription": "subscription",
"workspace.payments.view": "View",
"workspace.black.loading": "Loading...",
"workspace.black.time.day": "day",
"workspace.black.time.days": "days",
"workspace.black.time.hour": "hour",
@@ -669,7 +668,7 @@ export const dict = {
"workspace.black.time.fewSeconds": "a few seconds",
"workspace.black.subscription.title": "Subscription",
"workspace.black.subscription.message": "You are subscribed to OpenCode Black for ${{plan}} per month.",
"workspace.black.subscription.manage": "Manage Subscription",
"workspace.black.subscription.ending": "OpenCode Black ends with your current billing period and won't renew. We'll move you to the new console.",
"workspace.black.subscription.rollingUsage": "5-hour Usage",
"workspace.black.subscription.weeklyUsage": "Weekly Usage",
"workspace.black.subscription.resetsIn": "Resets in",
+1 -2
View File
@@ -665,7 +665,6 @@ export const dict = {
"workspace.payments.type.subscription": "suscripción",
"workspace.payments.view": "Ver",
"workspace.black.loading": "Cargando...",
"workspace.black.time.day": "día",
"workspace.black.time.days": "días",
"workspace.black.time.hour": "hora",
@@ -675,7 +674,7 @@ export const dict = {
"workspace.black.time.fewSeconds": "unos pocos segundos",
"workspace.black.subscription.title": "Suscripción",
"workspace.black.subscription.message": "Estás suscrito a OpenCode Black por ${{plan}} al mes.",
"workspace.black.subscription.manage": "Gestionar Suscripción",
"workspace.black.subscription.ending": "OpenCode Black finaliza con tu periodo de facturación actual y no se renovará. Te trasladaremos a la nueva consola.",
"workspace.black.subscription.rollingUsage": "Uso de 5 horas",
"workspace.black.subscription.weeklyUsage": "Uso Semanal",
"workspace.black.subscription.resetsIn": "Se reinicia en",
+1 -2
View File
@@ -667,7 +667,6 @@ export const dict = {
"workspace.payments.type.subscription": "abonnement",
"workspace.payments.view": "Voir",
"workspace.black.loading": "Chargement...",
"workspace.black.time.day": "jour",
"workspace.black.time.days": "jours",
"workspace.black.time.hour": "heure",
@@ -677,7 +676,7 @@ export const dict = {
"workspace.black.time.fewSeconds": "quelques secondes",
"workspace.black.subscription.title": "Abonnement",
"workspace.black.subscription.message": "Vous êtes abonné à OpenCode Black pour {{plan}} $ par mois.",
"workspace.black.subscription.manage": "Gérer l'abonnement",
"workspace.black.subscription.ending": "OpenCode Black prend fin avec votre période de facturation actuelle et ne sera pas renouvelé. Nous vous migrerons vers la nouvelle console.",
"workspace.black.subscription.rollingUsage": "Utilisation 5 heures",
"workspace.black.subscription.weeklyUsage": "Utilisation hebdomadaire",
"workspace.black.subscription.resetsIn": "Réinitialisation dans",
+1 -2
View File
@@ -663,7 +663,6 @@ export const dict = {
"workspace.payments.type.subscription": "abbonamento",
"workspace.payments.view": "Visualizza",
"workspace.black.loading": "Caricamento...",
"workspace.black.time.day": "giorno",
"workspace.black.time.days": "giorni",
"workspace.black.time.hour": "ora",
@@ -673,7 +672,7 @@ export const dict = {
"workspace.black.time.fewSeconds": "pochi secondi",
"workspace.black.subscription.title": "Abbonamento",
"workspace.black.subscription.message": "Sei abbonato a OpenCode Black per ${{plan}} al mese.",
"workspace.black.subscription.manage": "Gestisci Abbonamento",
"workspace.black.subscription.ending": "OpenCode Black termina con il periodo di fatturazione in corso e non verrà rinnovato. Ti trasferiremo nella nuova console.",
"workspace.black.subscription.rollingUsage": "Utilizzo 5-ore",
"workspace.black.subscription.weeklyUsage": "Utilizzo Settimanale",
"workspace.black.subscription.resetsIn": "Si resetta tra",
+1 -2
View File
@@ -660,7 +660,6 @@ export const dict = {
"workspace.payments.type.subscription": "サブスクリプション",
"workspace.payments.view": "表示",
"workspace.black.loading": "読み込み中...",
"workspace.black.time.day": "日",
"workspace.black.time.days": "日",
"workspace.black.time.hour": "時間",
@@ -670,7 +669,7 @@ export const dict = {
"workspace.black.time.fewSeconds": "数秒",
"workspace.black.subscription.title": "サブスクリプション",
"workspace.black.subscription.message": "あなたは OpenCode Black を月額 ${{plan}} で購読しています。",
"workspace.black.subscription.manage": "サブスクリプションの管理",
"workspace.black.subscription.ending": "OpenCode Black は現在の請求期間の終了とともに終了し、更新されません。新しいコンソールへ移行いたします。",
"workspace.black.subscription.rollingUsage": "5時間利用",
"workspace.black.subscription.weeklyUsage": "週間利用量",
"workspace.black.subscription.resetsIn": "リセットまで",
+1 -2
View File
@@ -653,7 +653,6 @@ export const dict = {
"workspace.payments.type.subscription": "구독",
"workspace.payments.view": "보기",
"workspace.black.loading": "로드 중...",
"workspace.black.time.day": "일",
"workspace.black.time.days": "일",
"workspace.black.time.hour": "시간",
@@ -663,7 +662,7 @@ export const dict = {
"workspace.black.time.fewSeconds": "몇 초",
"workspace.black.subscription.title": "구독",
"workspace.black.subscription.message": "현재 월 ${{plan}} OpenCode Black 플랜을 구독 중입니다.",
"workspace.black.subscription.manage": "구독 관리",
"workspace.black.subscription.ending": "OpenCode Black은 현재 결제 기간이 끝나면 종료되며 갱신되지 않습니다. 새 콘솔로 옮겨 드리겠습니다.",
"workspace.black.subscription.rollingUsage": "5시간 사용량",
"workspace.black.subscription.weeklyUsage": "주간 사용량",
"workspace.black.subscription.resetsIn": "초기화까지 남은 시간:",
+1 -2
View File
@@ -661,7 +661,6 @@ export const dict = {
"workspace.payments.type.subscription": "abonnement",
"workspace.payments.view": "Vis",
"workspace.black.loading": "Laster...",
"workspace.black.time.day": "dag",
"workspace.black.time.days": "dager",
"workspace.black.time.hour": "time",
@@ -671,7 +670,7 @@ export const dict = {
"workspace.black.time.fewSeconds": "noen få sekunder",
"workspace.black.subscription.title": "Abonnement",
"workspace.black.subscription.message": "Du abonnerer på OpenCode Black for ${{plan}} per måned.",
"workspace.black.subscription.manage": "Administrer abonnement",
"workspace.black.subscription.ending": "OpenCode Black avsluttes med gjeldende faktureringsperiode og fornyes ikke. Vi flytter deg til den nye konsollen.",
"workspace.black.subscription.rollingUsage": "5-timers bruk",
"workspace.black.subscription.weeklyUsage": "Ukentlig bruk",
"workspace.black.subscription.resetsIn": "Nullstilles om",
+1 -2
View File
@@ -662,7 +662,6 @@ export const dict = {
"workspace.payments.type.subscription": "subskrypcja",
"workspace.payments.view": "Zobacz",
"workspace.black.loading": "Ładowanie...",
"workspace.black.time.day": "dzień",
"workspace.black.time.days": "dni",
"workspace.black.time.hour": "godzina",
@@ -672,7 +671,7 @@ export const dict = {
"workspace.black.time.fewSeconds": "kilka sekund",
"workspace.black.subscription.title": "Subskrypcja",
"workspace.black.subscription.message": "Subskrybujesz OpenCode Black za ${{plan}} miesięcznie.",
"workspace.black.subscription.manage": "Zarządzaj subskrypcją",
"workspace.black.subscription.ending": "OpenCode Black kończy się wraz z bieżącym okresem rozliczeniowym i nie zostanie odnowiony. Przeniesiemy Cię do nowej konsoli.",
"workspace.black.subscription.rollingUsage": "Użycie (okno 5h)",
"workspace.black.subscription.weeklyUsage": "Użycie tygodniowe",
"workspace.black.subscription.resetsIn": "Resetuje się za",
+1 -2
View File
@@ -669,7 +669,6 @@ export const dict = {
"workspace.payments.type.subscription": "подписка",
"workspace.payments.view": "Просмотр",
"workspace.black.loading": "Загрузка...",
"workspace.black.time.day": "день",
"workspace.black.time.days": "дней",
"workspace.black.time.hour": "час",
@@ -679,7 +678,7 @@ export const dict = {
"workspace.black.time.fewSeconds": "несколько секунд",
"workspace.black.subscription.title": "Подписка",
"workspace.black.subscription.message": "Вы подписаны на OpenCode Black за ${{plan}} в месяц.",
"workspace.black.subscription.manage": "Управление подпиской",
"workspace.black.subscription.ending": "OpenCode Black завершится в конце текущего расчётного периода и не будет продлён. Мы перенесём вас в новую консоль.",
"workspace.black.subscription.rollingUsage": "5-часовое использование",
"workspace.black.subscription.weeklyUsage": "Недельное использование",
"workspace.black.subscription.resetsIn": "Сброс через",
+1 -2
View File
@@ -658,7 +658,6 @@ export const dict = {
"workspace.payments.type.subscription": "subscription",
"workspace.payments.view": "ดู",
"workspace.black.loading": "กำลังโหลด...",
"workspace.black.time.day": "วัน",
"workspace.black.time.days": "วัน",
"workspace.black.time.hour": "ชั่วโมง",
@@ -668,7 +667,7 @@ export const dict = {
"workspace.black.time.fewSeconds": "ไม่กี่วินาที",
"workspace.black.subscription.title": "การสมัครสมาชิก",
"workspace.black.subscription.message": "คุณสมัครสมาชิก OpenCode Black ในราคา ${{plan}} ต่อเดือน",
"workspace.black.subscription.manage": "จัดการการสมัครสมาชิก",
"workspace.black.subscription.ending": "OpenCode Black จะสิ้นสุดเมื่อครบรอบการเรียกเก็บเงินปัจจุบันและจะไม่ต่ออายุ เราจะย้ายคุณไปยังคอนโซลใหม่",
"workspace.black.subscription.rollingUsage": "การใช้งาน 5 ชั่วโมง",
"workspace.black.subscription.weeklyUsage": "การใช้งานรายสัปดาห์",
"workspace.black.subscription.resetsIn": "รีเซ็ตใน",
+1 -2
View File
@@ -664,7 +664,6 @@ export const dict = {
"workspace.payments.type.subscription": "abonelik",
"workspace.payments.view": "Görüntüle",
"workspace.black.loading": "Yükleniyor...",
"workspace.black.time.day": "gün",
"workspace.black.time.days": "gün",
"workspace.black.time.hour": "saat",
@@ -674,7 +673,7 @@ export const dict = {
"workspace.black.time.fewSeconds": "birkaç saniye",
"workspace.black.subscription.title": "Abonelik",
"workspace.black.subscription.message": "Aylık ${{plan}} karşılığında OpenCode Black'e abonesiniz.",
"workspace.black.subscription.manage": "Aboneliği Yönet",
"workspace.black.subscription.ending": "OpenCode Black mevcut fatura döneminizin sonunda sona erer ve yenilenmez. Sizi yeni konsola taşıyacağız.",
"workspace.black.subscription.rollingUsage": "5 Saatlik Kullanım",
"workspace.black.subscription.weeklyUsage": "Haftalık Kullanım",
"workspace.black.subscription.resetsIn": "Sıfırlama süresi",
+1 -2
View File
@@ -659,7 +659,6 @@ export const dict = {
"workspace.payments.type.subscription": "підписка",
"workspace.payments.view": "Переглянути",
"workspace.black.loading": "Завантаження...",
"workspace.black.time.day": "день",
"workspace.black.time.days": "дні",
"workspace.black.time.hour": "година",
@@ -669,7 +668,7 @@ export const dict = {
"workspace.black.time.fewSeconds": "кілька секунд",
"workspace.black.subscription.title": "Підписка",
"workspace.black.subscription.message": "Ви підписані на OpenCode Black за ${{plan}} на місяць.",
"workspace.black.subscription.manage": "Керувати підпискою",
"workspace.black.subscription.ending": "OpenCode Black завершиться наприкінці поточного розрахункового періоду й не буде подовжений. Ми перенесемо вас до нової консолі.",
"workspace.black.subscription.rollingUsage": "Використання (5 год)",
"workspace.black.subscription.weeklyUsage": "Тижневе використання",
"workspace.black.subscription.resetsIn": "Скидається через",
+1 -2
View File
@@ -634,7 +634,6 @@ export const dict = {
"workspace.payments.type.subscription": "订阅",
"workspace.payments.view": "查看",
"workspace.black.loading": "加载中...",
"workspace.black.time.day": "天",
"workspace.black.time.days": "天",
"workspace.black.time.hour": "小时",
@@ -644,7 +643,7 @@ export const dict = {
"workspace.black.time.fewSeconds": "几秒钟",
"workspace.black.subscription.title": "订阅",
"workspace.black.subscription.message": "您已订阅 OpenCode Black,价格为每月 ${{plan}}。",
"workspace.black.subscription.manage": "管理订阅",
"workspace.black.subscription.ending": "OpenCode Black 将在当前计费周期结束时终止,不会续订。我们会将你迁移到新的控制台。",
"workspace.black.subscription.rollingUsage": "5 小时用量",
"workspace.black.subscription.weeklyUsage": "每周用量",
"workspace.black.subscription.resetsIn": "重置于",
+1 -2
View File
@@ -633,7 +633,6 @@ export const dict = {
"workspace.payments.type.subscription": "訂閱",
"workspace.payments.view": "檢視",
"workspace.black.loading": "載入中...",
"workspace.black.time.day": "天",
"workspace.black.time.days": "天",
"workspace.black.time.hour": "小時",
@@ -643,7 +642,7 @@ export const dict = {
"workspace.black.time.fewSeconds": "幾秒鐘",
"workspace.black.subscription.title": "訂閱",
"workspace.black.subscription.message": "你已訂閱 OpenCode Black,費用為每月 ${{plan}}。",
"workspace.black.subscription.manage": "管理訂閱",
"workspace.black.subscription.ending": "OpenCode Black 將於目前計費週期結束時終止,不會續訂。我們會將你遷移至新的控制台。",
"workspace.black.subscription.rollingUsage": "5 小時使用量",
"workspace.black.subscription.weeklyUsage": "每週使用量",
"workspace.black.subscription.resetsIn": "重置於",
@@ -195,6 +195,18 @@ export async function POST(input: APIEvent) {
await Billing.unsubscribeBlack({ subscriptionID })
}
}
if (body.type === "customer.subscription.updated") {
// Black is retired: no subscription may renew, so undo any renewal made in the billing portal.
const subscription = body.data.object
if (subscription.items.data[0].price.product !== BlackData.productID()) return "ignored"
if (!["active", "trialing", "past_due"].includes(subscription.status)) return "ignored"
if (subscription.cancel_at_period_end || subscription.cancel_at) return "ignored"
await Billing.stripe().subscriptions.update(subscription.id, {
cancel_at_period_end: true,
cancellation_details: { comment: "Legacy Black retirement: renewal is not allowed" },
})
}
if (body.type === "customer.subscription.deleted") {
const subscriptionID = body.data.object.id
if (!subscriptionID) throw new Error("Subscription ID not found")
@@ -1,11 +1,4 @@
.root {
[data-slot="title-row"] {
display: flex;
justify-content: space-between;
align-items: center;
gap: var(--space-4);
}
[data-slot="usage"] {
display: flex;
gap: var(--space-6);
@@ -84,23 +84,6 @@ const enroll = action(async (workspaceID: string) => {
)
}, "enroll")
const createSessionUrl = action(async (workspaceID: string, returnUrl: string) => {
"use server"
return json(
await withActor(
() =>
Billing.generateSessionUrl({ returnUrl })
.then((data) => ({ error: undefined, data }))
.catch((e) => ({
error: e.message as string,
data: undefined,
})),
workspaceID,
),
{ revalidate: [queryBillingInfo.key, querySubscription.key] },
)
}, "sessionUrl")
const setUseBalance = action(async (form: FormData) => {
"use server"
const workspaceID = form.get("workspaceID") as string | null
@@ -130,27 +113,16 @@ export function BlackSection() {
const i18n = useI18n()
const billing = createAsync(() => queryBillingInfo(params.id!))
const subscription = createAsync(() => querySubscription(params.id!))
const sessionAction = useAction(createSessionUrl)
const sessionSubmission = useSubmission(createSessionUrl)
const cancelAction = useAction(cancelWaitlist)
const cancelSubmission = useSubmission(cancelWaitlist)
const enrollAction = useAction(enroll)
const enrollSubmission = useSubmission(enroll)
const useBalanceSubmission = useSubmission(setUseBalance)
const [store, setStore] = createStore({
sessionRedirecting: false,
cancelled: false,
enrolled: false,
})
async function onClickSession() {
const result = await sessionAction(params.id!, window.location.href)
if (result.data) {
setStore("sessionRedirecting", true)
window.location.href = result.data
}
}
async function onClickCancel() {
const result = await cancelAction(params.id!)
if (!result.error) {
@@ -172,18 +144,8 @@ export function BlackSection() {
<section class={styles.root}>
<div data-slot="section-title">
<h2>{i18n.t("workspace.black.subscription.title")}</h2>
<div data-slot="title-row">
<p>{i18n.t("workspace.black.subscription.message", { plan: sub().plan })}</p>
<button
data-color="primary"
disabled={sessionSubmission.pending || store.sessionRedirecting}
onClick={onClickSession}
>
{sessionSubmission.pending || store.sessionRedirecting
? i18n.t("workspace.black.loading")
: i18n.t("workspace.black.subscription.manage")}
</button>
</div>
<p>{i18n.t("workspace.black.subscription.ending")}</p>
</div>
<div data-slot="usage">
<div data-slot="usage-item">