chore: tighten education verification and pause discount access (#40402)

Co-authored-by: Yansong Zhang <916125788@qq.com>
This commit is contained in:
Joel
2026-08-10 06:33:03 +00:00
committed by GitHub
co-authored by Yansong Zhang
parent 7e7548cd18
commit 5967bd8e08
34 changed files with 472 additions and 78 deletions
@@ -4,8 +4,7 @@ import type { ReactElement } from 'react'
* Integration test: Education Verification Flow
*
* Tests the education plan verification flow in PlanComp:
* PlanComp → handleVerify → useEducationVerify → router.push → education-apply
* PlanComp → handleVerify → error → show VerifyStateModal
* PlanComp → handleVerify → show temporary pause notice
*
* Also covers education button visibility based on context flags.
*/
@@ -102,14 +101,16 @@ vi.mock('@/app/education-apply/verify-state-modal', () => ({
}: {
isShow: boolean
title?: string
content?: string
content?: React.ReactNode
email?: string
showLink?: boolean
}) =>
isShow ? (
<div data-testid="verify-state-modal">
{title && <span data-testid="modal-title">{title}</span>}
{content && <span data-testid="modal-content">{content}</span>}
{content !== undefined && content !== null ? (
<span data-testid="modal-content">{content}</span>
) : null}
{email && <span data-testid="modal-email">{email}</span>}
{showLink && <span data-testid="modal-show-link">link</span>}
</div>
@@ -208,67 +209,9 @@ describe('Education Verification Flow', () => {
})
})
// ─── 2. Successful Verification Flow ────────────────────────────────────
describe('Successful verification flow', () => {
it('should let non-manager members start education verification', async () => {
mockMutateAsync.mockResolvedValue({ token: 'edu-token-123' })
setupContexts({}, { enableEducationPlan: true }, { isCurrentWorkspaceManager: false })
const user = userEvent.setup()
render(<PlanComp loc="test" />)
const verifyButton = screen.getByText(/toVerified/i)
await user.click(verifyButton)
await waitFor(() => {
expect(mockMutateAsync).toHaveBeenCalledTimes(1)
expect(mockRouterPush).toHaveBeenCalledWith('/education-apply?token=edu-token-123')
})
})
})
// ─── 3. Failed Verification Flow ────────────────────────────────────────
describe('Failed verification flow', () => {
it('should show VerifyStateModal with rejection info on error', async () => {
mockMutateAsync.mockRejectedValue(new Error('Verification failed'))
setupContexts({}, { enableEducationPlan: true })
const user = userEvent.setup()
render(<PlanComp loc="test" />)
// Modal should not be visible initially
expect(screen.queryByTestId('verify-state-modal')).not.toBeInTheDocument()
const verifyButton = screen.getByText(/toVerified/i)
await user.click(verifyButton)
// Modal should appear after verification failure
await waitFor(() => {
expect(screen.getByTestId('verify-state-modal')).toBeInTheDocument()
})
// Modal should display rejection title and content
expect(screen.getByTestId('modal-title')).toHaveTextContent(/rejectTitle/i)
expect(screen.getByTestId('modal-content')).toHaveTextContent(/rejectContent/i)
})
it('should show email and link in VerifyStateModal', async () => {
mockMutateAsync.mockRejectedValue(new Error('fail'))
setupContexts({}, { enableEducationPlan: true })
const user = userEvent.setup()
render(<PlanComp loc="test" />)
await user.click(screen.getByText(/toVerified/i))
await waitFor(() => {
expect(screen.getByTestId('modal-email')).toHaveTextContent('student@university.edu')
expect(screen.getByTestId('modal-show-link')).toBeInTheDocument()
})
})
it('should not redirect on verification failure', async () => {
mockMutateAsync.mockRejectedValue(new Error('fail'))
// ─── 2. Temporarily Paused Verification Flow ────────────────────────────
describe('Temporarily paused verification flow', () => {
it('should show the pause notice without starting verification', async () => {
setupContexts({}, { enableEducationPlan: true })
const user = userEvent.setup()
@@ -280,12 +223,18 @@ describe('Education Verification Flow', () => {
expect(screen.getByTestId('verify-state-modal')).toBeInTheDocument()
})
// Should NOT navigate
expect(screen.getByTestId('modal-title')).toHaveTextContent(/educationDiscountPaused.title/i)
expect(screen.getByTestId('modal-content')).toHaveTextContent(
/educationDiscountPaused.description/i,
)
expect(screen.queryByTestId('modal-email')).not.toBeInTheDocument()
expect(screen.queryByTestId('modal-show-link')).not.toBeInTheDocument()
expect(mockMutateAsync).not.toHaveBeenCalled()
expect(mockRouterPush).not.toHaveBeenCalled()
})
})
// ─── 4. Education + Upgrade Coexistence ─────────────────────────────────
// ─── 3. Education + Upgrade Coexistence ─────────────────────────────────
describe('Education and upgrade button coexistence', () => {
it('should show both education verify and upgrade buttons for sandbox user', () => {
setupContexts({ type: Plan.sandbox }, { enableEducationPlan: true })
+36
View File
@@ -0,0 +1,36 @@
import { beforeEach, describe, expect, it, vi } from 'vitest'
const mocks = vi.hoisted(() => ({
redirect: vi.fn((url: string) => {
throw new Error(`NEXT_REDIRECT:${url}`)
}),
}))
vi.mock('@/features/home/page', () => ({
HomePage: () => null,
}))
vi.mock('@/next/navigation', () => ({
redirect: (url: string) => mocks.redirect(url),
}))
describe('Home route', () => {
beforeEach(() => {
vi.clearAllMocks()
})
it('opens billing for the legacy education verification action', async () => {
const { default: Page } = await import('./page')
await expect(
Page({
searchParams: Promise.resolve({
action: 'getEducationVerify',
utm_source: 'education-email',
}),
}),
).rejects.toThrow('NEXT_REDIRECT')
expect(mocks.redirect).toHaveBeenCalledWith('/?settings=billing&utm_source=education-email')
})
})
+43 -1
View File
@@ -1,5 +1,47 @@
import { ACCOUNT_SETTING_TAB } from '@/app/components/header/account-setting/constants'
import { HomePage } from '@/features/home/page'
import { redirect } from '@/next/navigation'
type HomeSearchParams = Record<string, string | string[] | undefined>
type PageProps = {
searchParams?: Promise<HomeSearchParams>
}
const LEGACY_EDUCATION_VERIFY_ACTION = 'getEducationVerify'
const SETTINGS_QUERY_PARAM_NAME = 'settings'
const getFirstSearchParamValue = (value: string | string[] | undefined) => {
if (Array.isArray(value)) return value[0]
return value
}
const getEducationVerifyRedirectPath = (searchParams: HomeSearchParams) => {
const redirectSearchParams = new URLSearchParams({
[SETTINGS_QUERY_PARAM_NAME]: ACCOUNT_SETTING_TAB.BILLING,
})
Object.entries(searchParams).forEach(([key, value]) => {
if (key === 'action' || key === SETTINGS_QUERY_PARAM_NAME || value === undefined) return
if (Array.isArray(value)) {
value.forEach((item) => redirectSearchParams.append(key, item))
return
}
redirectSearchParams.append(key, value)
})
return `/?${redirectSearchParams.toString()}`
}
export default async function Page({ searchParams }: PageProps) {
const resolvedSearchParams = (await searchParams) ?? {}
const action = getFirstSearchParamValue(resolvedSearchParams.action)
if (action === LEGACY_EDUCATION_VERIFY_ACTION)
redirect(getEducationVerifyRedirectPath(resolvedSearchParams))
export default function Page() {
return <HomePage />
}
@@ -0,0 +1,129 @@
import { screen, within } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { baseProviderContextValue } from '@/context/provider-context'
import { createConsoleQueryWrapper } from '@/test/console/query-data'
import { render } from '@/test/console/render'
import PlanComp from '../index'
const mocks = vi.hoisted(() => ({
mutateAsync: vi.fn(),
push: vi.fn(),
}))
vi.mock('@/context/account-state', async () => {
const { createAccountStateModuleMock } = await import('@/test/console/state-fixture')
return createAccountStateModuleMock(() => ({
userProfile: { email: 'user@example.com' },
}))
})
vi.mock('@/context/workspace-state', async () => {
const { createWorkspaceStateModuleMock } = await import('@/test/console/state-fixture')
return createWorkspaceStateModuleMock(() => ({
isCurrentWorkspaceManager: false,
}))
})
vi.mock('@/context/provider-context', async (importOriginal) => {
const actual = await importOriginal<typeof import('@/context/provider-context')>()
return {
...actual,
useProviderContext: () => ({
...baseProviderContextValue,
enableEducationPlan: true,
}),
}
})
vi.mock('@/next/navigation', () => ({
useRouter: () => ({ push: mocks.push }),
}))
vi.mock('@/service/use-education', () => ({
useEducationVerify: () => ({
isPending: false,
mutateAsync: mocks.mutateAsync,
}),
}))
vi.mock('@/app/components/billing/hooks/use-education-discount', () => ({
useEducationDiscount: () => ({
handleEducationDiscount: vi.fn(),
isEducationDiscountLoading: false,
}),
}))
vi.mock('@/app/components/billing/upgrade-btn', () => ({
default: () => <button type="button">View Plan</button>,
}))
vi.mock('@/app/components/billing/usage-info', () => ({
default: () => null,
}))
vi.mock('@/app/components/billing/usage-info/apps-info', () => ({
default: () => null,
}))
vi.mock('@/app/components/billing/usage-info/vector-space-info', () => ({
default: () => null,
}))
vi.mock('../assets', () => ({
Enterprise: () => null,
Professional: () => null,
Sandbox: () => null,
Team: () => null,
}))
const renderPlan = (educationStatus = { allow_refresh: false, is_student: false }) => {
const { wrapper } = createConsoleQueryWrapper({
educationStatus,
systemFeatures: { deployment_edition: 'CLOUD' },
})
return render(<PlanComp loc="billing-page" />, { wrapper })
}
describe('PlanComp education discount pause', () => {
beforeEach(() => {
vi.clearAllMocks()
})
it('shows education verification before View Plan when the original eligibility allows it', () => {
renderPlan()
const educationButton = screen.getByRole('button', { name: 'education.toVerified' })
const viewPlanButton = screen.getByRole('button', { name: 'View Plan' })
expect(
educationButton.compareDocumentPosition(viewPlanButton) & Node.DOCUMENT_POSITION_FOLLOWING,
).toBeTruthy()
})
it('hides education verification for a verified account that is not expiring', () => {
renderPlan({ allow_refresh: false, is_student: true })
expect(screen.queryByRole('button', { name: 'education.toVerified' })).not.toBeInTheDocument()
})
it('shows the pause notice instead of starting verification and closes it with OK', async () => {
const user = userEvent.setup()
renderPlan()
await user.click(screen.getByRole('button', { name: 'education.toVerified' }))
const dialog = await screen.findByRole('dialog')
expect(dialog).toHaveTextContent('education.educationDiscountPaused.title')
expect(dialog).toHaveTextContent('education.educationDiscountPaused.description')
expect(dialog).toHaveTextContent('education.educationDiscountPaused.thanks')
expect(dialog).toHaveTextContent('education.educationDiscountPaused.publishedAt')
expect(within(dialog).getAllByRole('button')).toHaveLength(1)
expect(within(dialog).getByRole('button')).toHaveAccessibleName('common.operation.ok')
expect(mocks.mutateAsync).not.toHaveBeenCalled()
await user.click(screen.getByRole('button', { name: 'common.operation.ok' }))
expect(screen.queryByRole('dialog')).not.toBeInTheDocument()
})
})
+29
View File
@@ -37,6 +37,9 @@ const selectEducationPlanStatus = ({ allow_refresh, is_student }: EducationStatu
isEducationAccount: is_student ?? false,
})
// TODO: Remove this temporary gate once education applications and redemptions reopen.
const EDUCATION_DISCOUNT_TEMPORARILY_PAUSED = true
const PlanComp: FC<Props> = ({ loc }) => {
const { t } = useTranslation()
const { data: deploymentEdition } = useSuspenseQuery({
@@ -71,10 +74,17 @@ const PlanComp: FC<Props> = ({ loc }) => {
})()
const [showModal, setShowModal] = React.useState(false)
const [showEducationDiscountPausedModal, setShowEducationDiscountPausedModal] =
React.useState(false)
const { handleEducationDiscount, isEducationDiscountLoading } = useEducationDiscount()
const { mutateAsync, isPending } = useEducationVerify()
const unmountedRef = useUnmountedRef()
const handleVerify = () => {
if (EDUCATION_DISCOUNT_TEMPORARILY_PAUSED) {
setShowEducationDiscountPausedModal(true)
return
}
if (isPending) return
mutateAsync()
.then((res) => {
@@ -175,6 +185,25 @@ const PlanComp: FC<Props> = ({ loc }) => {
resetInDays={apiRateLimitResetInDays}
/>
</div>
<VerifyStateModal
isShow={showEducationDiscountPausedModal}
title={t(($) => $['educationDiscountPaused.title'], { ns: 'education' })}
content={
<>
<span className="block">
{t(($) => $['educationDiscountPaused.description'], { ns: 'education' })}
</span>
<span className="mt-4 block">
{t(($) => $['educationDiscountPaused.thanks'], { ns: 'education' })}
</span>
<span className="mt-4 block system-xs-regular">
{t(($) => $['educationDiscountPaused.publishedAt'], { ns: 'education' })}
</span>
</>
}
onConfirm={() => setShowEducationDiscountPausedModal(false)}
onCancel={() => setShowEducationDiscountPausedModal(false)}
/>
<VerifyStateModal
showLink
email={userProfileEmail}
@@ -57,6 +57,14 @@ vi.mock('@/service/use-common', () => ({
useLogout: () => ({ mutateAsync: vi.fn() }),
}))
vi.mock('@/service/use-education', () => ({
useEducationAutocomplete: () => ({
mutateAsync: vi.fn().mockResolvedValue({ data: [], has_next: false }),
isPending: false,
data: undefined,
}),
}))
vi.mock('@/hooks/use-async-window-open', () => ({
useAsyncWindowOpen: () => vi.fn(),
}))
@@ -125,9 +133,9 @@ const setupContext = (isCurrentWorkspaceManager: boolean) => {
}
}
const renderPage = () => {
const renderPage = (isEducationAccount = true) => {
const { wrapper } = createConsoleQueryWrapper({
educationStatus: { is_student: true },
educationStatus: { is_student: isEducationAccount },
workspacePermissionKeys: null,
})
return render(<EducationApplyPage />, {
@@ -221,4 +229,39 @@ describe('EducationApplyPage billing boundary', () => {
})
expect(globalThis.location.reload).not.toHaveBeenCalled()
})
it('requires every education agreement before submitting an application', async () => {
setupContext(true)
mockEducationAdd.mockResolvedValue({ message: 'success' })
const user = userEvent.setup()
renderPage(false)
const submitButton = screen.getByRole('button', { name: 'education.submit' })
await user.type(
screen.getByPlaceholderText('education.form.schoolName.placeholder'),
'DifyUniversity',
)
await user.click(screen.getByRole('checkbox', { name: 'education.form.terms.option.age' }))
await user.click(screen.getByRole('checkbox', { name: 'education.form.terms.option.inSchool' }))
expect(submitButton).toBeDisabled()
await user.click(
screen.getByRole('checkbox', { name: 'education.form.terms.option.personalUse' }),
)
expect(submitButton).toBeEnabled()
await user.click(submitButton)
await waitFor(() => {
expect(mockEducationAdd.mock.calls[0]?.[0]).toEqual({
body: {
token: 'education-token',
role: 'Student',
institution: 'DifyUniversity',
},
})
})
})
})
@@ -36,6 +36,7 @@ const EducationApplyAgeContent = () => {
const [role, setRole] = useState('Student')
const [ageChecked, setAgeChecked] = useState(false)
const [inSchoolChecked, setInSchoolChecked] = useState(false)
const [personalUseChecked, setPersonalUseChecked] = useState(false)
const [hasSubmittedEducation, setHasSubmittedEducation] = useState(false)
const [isOpeningBillingPortal, setIsOpeningBillingPortal] = useState(false)
const { isPending, mutateAsync: educationAdd } = useMutation(
@@ -262,7 +263,7 @@ const EducationApplyAgeContent = () => {
/>
{t(($) => $['form.terms.option.age'], { ns: 'education' })}
</label>
<label className="flex">
<label className="mb-2 flex">
<Checkbox
className="mr-2 shrink-0"
checked={inSchoolChecked}
@@ -270,11 +271,26 @@ const EducationApplyAgeContent = () => {
/>
{t(($) => $['form.terms.option.inSchool'], { ns: 'education' })}
</label>
<label className="flex">
<Checkbox
className="mr-2 shrink-0"
checked={personalUseChecked}
onCheckedChange={setPersonalUseChecked}
/>
{t(($) => $['form.terms.option.personalUse'], { ns: 'education' })}
</label>
</div>
</div>
<Button
variant="primary"
disabled={!ageChecked || !inSchoolChecked || !schoolName || !role || isPending}
disabled={
!ageChecked ||
!inSchoolChecked ||
!personalUseChecked ||
!schoolName ||
!role ||
isPending
}
onClick={handleSubmit}
>
{t(($) => $.submit, { ns: 'education' })}
+5
View File
@@ -5,6 +5,10 @@
"applied.step1.description": "لقد قدمت بنجاح طلباً للحصول على الخصم التعليمي.",
"applied.step2.description": "اختر مساحة العمل التي تريد استخدامها مع الخصم التعليمي.",
"currentSigned": "تم تسجيل الدخول حاليًا باسم",
"educationDiscountPaused.description": "نظرًا للزيادة الأخيرة في الطلبات المشبوهة وإساءة الاستخدام، أوقفنا مؤقتًا الطلبات الجديدة وعمليات الاستفادة من الخصم بينما نعمل على ترقية إجراءاتنا الأمنية.",
"educationDiscountPaused.publishedAt": "نُشر في 10 أغسطس 2026",
"educationDiscountPaused.thanks": "شكرًا لتفهمكم.",
"educationDiscountPaused.title": "تم إيقاف الخصم التعليمي مؤقتًا",
"educationPricingConfirm.cancel": "الاحتفاظ بالخطة الحالية",
"educationPricingConfirm.continue": "التبديل إلى Professional السنوية",
"educationPricingConfirm.description": "ينطبق الخصم التعليمي على خطة Professional السنوية فقط. الاحتفاظ بخطتك الحالية لن يتضمن الخصم.",
@@ -23,6 +27,7 @@
"form.terms.desc.termsOfService": "شروط الخدمة",
"form.terms.option.age": "أؤكد أن عمري 18 عامًا على الأقل",
"form.terms.option.inSchool": "أؤكد أنني مسجل أو موظف في المؤسسة المقدمة. قد تطلب Dify إثبات التسجيل/التوظيف. إذا قدمت معلومات خاطئة حول أهليتي، فأوافق على دفع أي رسوم تم التنازل عنها مبدئيًا بناءً على حالة التعليم الخاصة بي.",
"form.terms.option.personalUse": "أؤكد أن حالة Education Verified الخاصة بي وجميع المزايا المرتبطة بها، بما في ذلك الخصومات والقسائم والأرصدة، مخصصة لاستخدامي الشخصي فقط. لن أبيعها أو أنقلها أو أشاركها أو أرخصها من الباطن أو أستخدمها لتوفير وصول مدفوع إلى خدمات Dify لأي طرف ثالث.",
"form.terms.title": "الشروط والاتفاقيات",
"learn": "تعرف على كيفية التحقق من التعليم",
"notice.action.dismiss": "تجاهل",
+5
View File
@@ -5,6 +5,10 @@
"applied.step1.description": "Sie haben erfolgreich den Bildungsrabatt beantragt.",
"applied.step2.description": "Wählen Sie den Arbeitsbereich aus, den Sie mit dem Bildungsrabatt verwenden möchten.",
"currentSigned": "DERZEIT ANGEMELDET ALS",
"educationDiscountPaused.description": "Aufgrund eines jüngsten Anstiegs verdächtiger Anträge und missbräuchlicher Nutzung haben wir neue Anträge und Einlösungen vorübergehend pausiert, während wir unsere Sicherheitsmaßnahmen verbessern.",
"educationDiscountPaused.publishedAt": "Veröffentlicht am 10. August 2026",
"educationDiscountPaused.thanks": "Vielen Dank für Ihr Verständnis.",
"educationDiscountPaused.title": "Bildungsrabatt vorübergehend pausiert",
"educationPricingConfirm.cancel": "Aktuellen Plan behalten",
"educationPricingConfirm.continue": "Zu Professional jährlich wechseln",
"educationPricingConfirm.description": "Der Bildungsrabatt gilt nur für den jährlichen Professional-Plan. Wenn Sie Ihren aktuellen Plan behalten, ist der Rabatt nicht enthalten.",
@@ -23,6 +27,7 @@
"form.terms.desc.termsOfService": "Nutzungsbedingungen",
"form.terms.option.age": "Ich bestätige, dass ich mindestens 18 Jahre alt bin.",
"form.terms.option.inSchool": "Ich bestätige, dass ich an der angegebenen Einrichtung eingeschrieben oder angestellt bin. Dify kann einen Nachweis über die Einschreibung/Anstellung anfordern. Wenn ich meine Berechtigung falsch darstelle, stimme ich zu, alle Gebühren zu zahlen, die aufgrund meines Bildungsstatus ursprünglich erlassen wurden.",
"form.terms.option.personalUse": "Ich bestätige, dass mein Status „Education Verified“ und alle damit verbundenen Vorteile, einschließlich Rabatten, Gutscheinen und Guthaben, ausschließlich für meinen persönlichen Gebrauch bestimmt sind. Ich werde sie weder verkaufen, übertragen, teilen oder unterlizenzieren noch verwenden, um Dritten gegen Bezahlung Zugang zu Dify-Diensten zu gewähren.",
"form.terms.title": "Allgemeine Geschäftsbedingungen",
"learn": "Erfahren Sie, wie Sie Ihre Ausbildung überprüfen lassen.",
"notice.action.dismiss": "Ablehnen",
+5
View File
@@ -5,6 +5,10 @@
"applied.step1.description": "You've successfully applied for the education discount.",
"applied.step2.description": "Select the workspace you want to use the education discount with.",
"currentSigned": "CURRENTLY SIGNED IN AS",
"educationDiscountPaused.description": "Due to a recent increase in suspicious applications and misuse, we have temporarily paused new applications and redemptions while we upgrade our security measures.",
"educationDiscountPaused.publishedAt": "Published August 10, 2026",
"educationDiscountPaused.thanks": "Thank you for your understanding.",
"educationDiscountPaused.title": "Education Discount Temporarily Paused",
"educationPricingConfirm.cancel": "Keep current plan",
"educationPricingConfirm.continue": "Switch to Professional Annual",
"educationPricingConfirm.description": "The education discount applies to the Professional annual plan only. Keeping your current plan won't include the discount.",
@@ -23,6 +27,7 @@
"form.terms.desc.termsOfService": "Terms of Service",
"form.terms.option.age": "I confirm I am at least 18 years old",
"form.terms.option.inSchool": "I confirm I am enrolled or employed at the institution provided. Dify may request proof of enrollment/employment. If I misrepresent my eligibility, I agree to pay any fees initially waived based on my education status.",
"form.terms.option.personalUse": "I confirm that my Education Verified status and all associated benefits, including discounts, coupons, and credits, are for my personal use only. I will not sell, transfer, share, sublicense, or use them to provide paid access to Dify services to any third party.",
"form.terms.title": "Terms & Agreements",
"learn": "Learn how to get education verified",
"notice.action.dismiss": "Dismiss",
+5
View File
@@ -5,6 +5,10 @@
"applied.step1.description": "Has solicitado exitosamente el descuento educativo.",
"applied.step2.description": "Selecciona el workspace que deseas usar con el descuento educativo.",
"currentSigned": "ACTUALMENTE CONECTADO COMO",
"educationDiscountPaused.description": "Debido al reciente aumento de solicitudes sospechosas y usos indebidos, hemos pausado temporalmente las nuevas solicitudes y los canjes mientras mejoramos nuestras medidas de seguridad.",
"educationDiscountPaused.publishedAt": "Publicado el 10 de agosto de 2026",
"educationDiscountPaused.thanks": "Gracias por tu comprensión.",
"educationDiscountPaused.title": "Descuento educativo pausado temporalmente",
"educationPricingConfirm.cancel": "Mantener el plan actual",
"educationPricingConfirm.continue": "Cambiar a Professional anual",
"educationPricingConfirm.description": "El descuento educativo solo se aplica al plan Professional anual. Si mantienes tu plan actual, no se incluirá el descuento.",
@@ -23,6 +27,7 @@
"form.terms.desc.termsOfService": "Términos de Servicio",
"form.terms.option.age": "Confirmo que tengo al menos 18 años",
"form.terms.option.inSchool": "Confirmo que estoy inscrito o empleado en la institución indicada. Dify puede solicitar prueba de inscripción/empleo. Si falseo mi elegibilidad, acepto pagar cualquier tarifa que se haya eximido inicialmente en función de mi estado educativo.",
"form.terms.option.personalUse": "Confirmo que mi estado de Education Verified y todos los beneficios asociados, incluidos descuentos, cupones y créditos, son exclusivamente para mi uso personal. No los venderé, transferiré, compartiré, sublicenciaré ni utilizaré para proporcionar a terceros acceso de pago a los servicios de Dify.",
"form.terms.title": "Términos y Acuerdos",
"learn": "Aprende cómo obtener la verificación de la educación",
"notice.action.dismiss": "Descartar",
+5
View File
@@ -5,6 +5,10 @@
"applied.step1.description": "درخواست تخفیف آموزشی شما با موفقیت ثبت شد.",
"applied.step2.description": "workspace‌ای را که می‌خواهید با تخفیف آموزشی استفاده کنید انتخاب کنید.",
"currentSigned": "اکنون به عنوان",
"educationDiscountPaused.description": "به دلیل افزایش اخیر درخواست‌های مشکوک و سوءاستفاده، تا زمانی که اقدامات امنیتی خود را ارتقا می‌دهیم، درخواست‌های جدید و استفاده از تخفیف را موقتاً متوقف کرده‌ایم.",
"educationDiscountPaused.publishedAt": "منتشرشده در ۱۰ اوت ۲۰۲۶",
"educationDiscountPaused.thanks": "از درک شما سپاسگزاریم.",
"educationDiscountPaused.title": "تخفیف آموزشی موقتاً متوقف شده است",
"educationPricingConfirm.cancel": "حفظ طرح فعلی",
"educationPricingConfirm.continue": "تغییر به Professional سالانه",
"educationPricingConfirm.description": "تخفیف آموزشی فقط برای طرح سالانه Professional اعمال می‌شود. با حفظ طرح فعلی، این تخفیف شامل نمی‌شود.",
@@ -23,6 +27,7 @@
"form.terms.desc.termsOfService": "شرایط خدمات",
"form.terms.option.age": "من تأیید می‌کنم که حداقل ۱۸ سال سن دارم",
"form.terms.option.inSchool": "من تأیید می‌کنم که در مؤسسه‌ای که نام برده شده، ثبت‌نام شده یا استخدام شده‌ام. دیفی ممکن است از من بخواهد مدرکی برای ثبت‌نام/استخدام ارائه دهم. اگر صلاحیتم را اشتباه نمایم، موافقت می‌کنم که هر گونه هزینه‌ای که به‌خاطر وضعیت تحصیلی من ابتدا معاف شده، پرداخت کنم.",
"form.terms.option.personalUse": "تأیید می‌کنم که وضعیت Education Verified من و همه مزایای مرتبط با آن، از جمله تخفیف‌ها، کوپن‌ها و اعتبارها، فقط برای استفاده شخصی من هستند. آن‌ها را نمی‌فروشم، منتقل نمی‌کنم، به اشتراک نمی‌گذارم، مجوز فرعی نمی‌دهم یا برای ارائه دسترسی پولی به خدمات Dify به هیچ شخص ثالثی استفاده نمی‌کنم.",
"form.terms.title": "شرایط و توافقات",
"learn": "یاد بگیرید چگونه مدارک تحصیلی خود را تأیید کنید",
"notice.action.dismiss": "رد کردن",
+5
View File
@@ -5,6 +5,10 @@
"applied.step1.description": "Vous avez fait la demande de remise éducative avec succès.",
"applied.step2.description": "Sélectionnez l'espace de travail que vous souhaitez utiliser avec la remise éducative.",
"currentSigned": "ACTUELLEMENT CONNECTÉ EN TANT QUE",
"educationDiscountPaused.description": "En raison dune récente augmentation des demandes suspectes et des utilisations abusives, nous avons temporairement suspendu les nouvelles demandes et les utilisations de la réduction pendant que nous renforçons nos mesures de sécurité.",
"educationDiscountPaused.publishedAt": "Publié le 10 août 2026",
"educationDiscountPaused.thanks": "Merci de votre compréhension.",
"educationDiscountPaused.title": "Réduction éducation temporairement suspendue",
"educationPricingConfirm.cancel": "Conserver le plan actuel",
"educationPricingConfirm.continue": "Passer à Professional annuel",
"educationPricingConfirm.description": "La remise éducation s'applique uniquement au plan Professional annuel. En conservant votre plan actuel, la remise ne sera pas incluse.",
@@ -23,6 +27,7 @@
"form.terms.desc.termsOfService": "Conditions d'utilisation",
"form.terms.option.age": "Je confirme que j'ai au moins 18 ans.",
"form.terms.option.inSchool": "Je confirme que je suis inscrit ou employé dans l'institution indiquée. Dify peut demander une preuve d'inscription/employé. Si je falsifie mon éligibilité, j'accepte de payer tous les frais initialement annulés en fonction de mon statut éducatif.",
"form.terms.option.personalUse": "Je confirme que mon statut Education Verified et tous les avantages associés, notamment les remises, coupons et crédits, sont réservés à mon usage personnel. Je ne les vendrai pas, ne les transférerai pas, ne les partagerai pas, ne les concéderai pas en sous-licence et ne les utiliserai pas pour fournir à un tiers un accès payant aux services Dify.",
"form.terms.title": "Conditions et accords",
"learn": "Apprenez comment faire vérifier votre éducation",
"notice.action.dismiss": "Rejeter",
+5
View File
@@ -5,6 +5,10 @@
"applied.step1.description": "आपने शिक्षा छूट के लिए सफलतापूर्वक आवेदन किया है।",
"applied.step2.description": "वह workspace चुनें जिसे आप शिक्षा छूट के साथ उपयोग करना चाहते हैं।",
"currentSigned": "वर्तमान में साइन इन किया गया है के रूप में",
"educationDiscountPaused.description": "हाल ही में संदिग्ध आवेदनों और दुरुपयोग में वृद्धि के कारण, सुरक्षा उपायों को बेहतर बनाते समय हमने नए आवेदन और छूट रिडेम्प्शन अस्थायी रूप से रोक दिए हैं।",
"educationDiscountPaused.publishedAt": "10 अगस्त 2026 को प्रकाशित",
"educationDiscountPaused.thanks": "आपकी समझ के लिए धन्यवाद।",
"educationDiscountPaused.title": "शिक्षा छूट अस्थायी रूप से रोकी गई",
"educationPricingConfirm.cancel": "वर्तमान प्लान रखें",
"educationPricingConfirm.continue": "Professional वार्षिक पर स्विच करें",
"educationPricingConfirm.description": "शिक्षा छूट केवल Professional वार्षिक प्लान पर लागू होती है। अपना वर्तमान प्लान रखने पर छूट शामिल नहीं होगी।",
@@ -23,6 +27,7 @@
"form.terms.desc.termsOfService": "सेवाओं की शर्तें",
"form.terms.option.age": "मैं पुष्टि करता हूँ कि मैं कम से कम 18 साल का हूँ",
"form.terms.option.inSchool": "मैं पुष्टि करता हूँ कि मैं दी गई संस्थान में नामांकित या नियुक्त हूं। Dify नामांकन/नियुक्ति का प्रमाण मांग सकता है। यदि मैं अपनी पात्रता का गलत वर्णन करता हूं, तो मैं सहमत हूं कि मैं अपने शिक्षा स्थिति के आधार पर किसी भी शुल्क का भुगतान करूं जो प्रारंभ में माफ किया गया था।",
"form.terms.option.personalUse": "मैं पुष्टि करता/करती हूँ कि मेरा Education Verified स्टेटस और उससे जुड़े सभी लाभ, जिनमें छूट, कूपन और क्रेडिट शामिल हैं, केवल मेरे व्यक्तिगत उपयोग के लिए हैं। मैं उन्हें किसी तीसरे पक्ष को बेचूँगा/बेचूँगी, हस्तांतरित, साझा या उप-लाइसेंस नहीं करूँगा/करूँगी और न ही Dify सेवाओं की सशुल्क पहुँच देने के लिए उनका उपयोग करूँगा/करूँगी।",
"form.terms.title": "नियम और शर्तें",
"learn": "शिक्षा को प्रमाणित कराने का तरीका सीखें",
"notice.action.dismiss": "अस्वीकृत करें",
+5
View File
@@ -5,6 +5,10 @@
"applied.step1.description": "Anda telah berhasil mengajukan diskon pendidikan.",
"applied.step2.description": "Pilih workspace yang ingin Anda gunakan dengan diskon pendidikan.",
"currentSigned": "SAAT INI MASUK SEBAGAI",
"educationDiscountPaused.description": "Karena peningkatan permohonan mencurigakan dan penyalahgunaan baru-baru ini, kami menghentikan sementara permohonan baru dan penukaran diskon selagi meningkatkan langkah-langkah keamanan kami.",
"educationDiscountPaused.publishedAt": "Diterbitkan 10 Agustus 2026",
"educationDiscountPaused.thanks": "Terima kasih atas pengertian Anda.",
"educationDiscountPaused.title": "Diskon pendidikan dihentikan sementara",
"educationPricingConfirm.cancel": "Tetap gunakan paket saat ini",
"educationPricingConfirm.continue": "Beralih ke Professional Tahunan",
"educationPricingConfirm.description": "Diskon pendidikan hanya berlaku untuk paket Professional tahunan. Jika tetap menggunakan paket saat ini, diskon tidak akan disertakan.",
@@ -23,6 +27,7 @@
"form.terms.desc.termsOfService": "Ketentuan Layanan",
"form.terms.option.age": "Saya mengonfirmasi bahwa saya berusia setidaknya 18 tahun",
"form.terms.option.inSchool": "Saya mengonfirmasi bahwa saya terdaftar atau dipekerjakan di lembaga yang disediakan. Dify dapat meminta bukti pendaftaran/pekerjaan. Jika saya salah menggambarkan kelayakan saya, saya setuju untuk membayar biaya apa pun yang awalnya dibebaskan berdasarkan status pendidikan saya.",
"form.terms.option.personalUse": "Saya mengonfirmasi bahwa status Education Verified saya dan semua manfaat terkait, termasuk diskon, kupon, dan kredit, hanya untuk penggunaan pribadi saya. Saya tidak akan menjual, mengalihkan, membagikan, memberikan sublisensi, atau menggunakannya untuk memberikan akses berbayar ke layanan Dify kepada pihak ketiga mana pun.",
"form.terms.title": "Syarat & Perjanjian",
"learn": "Pelajari cara mendapatkan verifikasi pendidikan",
"notice.action.dismiss": "Mengabaikan",
+5
View File
@@ -5,6 +5,10 @@
"applied.step1.description": "Hai fatto domanda per lo sconto educativo con successo.",
"applied.step2.description": "Seleziona il workspace che vuoi utilizzare con lo sconto educativo.",
"currentSigned": "ATTUALMENTE ACCEDUTO COME",
"educationDiscountPaused.description": "A causa del recente aumento di richieste sospette e utilizzi impropri, abbiamo temporaneamente sospeso le nuove richieste e lutilizzo degli sconti mentre potenziamo le nostre misure di sicurezza.",
"educationDiscountPaused.publishedAt": "Pubblicato il 10 agosto 2026",
"educationDiscountPaused.thanks": "Grazie per la comprensione.",
"educationDiscountPaused.title": "Sconto Education temporaneamente sospeso",
"educationPricingConfirm.cancel": "Mantieni il piano attuale",
"educationPricingConfirm.continue": "Passa a Professional annuale",
"educationPricingConfirm.description": "Lo sconto Education si applica solo al piano Professional annuale. Mantenendo il piano attuale, lo sconto non verrà incluso.",
@@ -23,6 +27,7 @@
"form.terms.desc.termsOfService": "Termini di servizio",
"form.terms.option.age": "Confermo di avere almeno 18 anni",
"form.terms.option.inSchool": "Confermo di essere iscritto o impiegato presso l'istituzione fornita. Dify può richiedere una prova di iscrizione/impegno. Se rappresento erroneamente la mia idoneità, accetto di pagare eventuali tasse inizialmente esonerate in base al mio stato di istruzione.",
"form.terms.option.personalUse": "Confermo che il mio stato Education Verified e tutti i vantaggi associati, inclusi sconti, coupon e crediti, sono esclusivamente per uso personale. Non li venderò, trasferirò, condividerò, concederò in sublicenza né li utilizzerò per fornire a terzi accesso a pagamento ai servizi Dify.",
"form.terms.title": "Termini e Accordi",
"learn": "Scopri come far verificare la tua istruzione",
"notice.action.dismiss": "Ignora",
+5
View File
@@ -5,6 +5,10 @@
"applied.step1.description": "教育割引の申請が成功しました。",
"applied.step2.description": "教育割引を使用するワークスペースを選択してください。",
"currentSigned": "現在ログイン中のアカウントは",
"educationDiscountPaused.description": "不審な申請や不正利用が最近増加しているため、セキュリティ対策の強化が完了するまで、新規申請と割引の利用を一時停止しています。",
"educationDiscountPaused.publishedAt": "2026年8月10日公開",
"educationDiscountPaused.thanks": "ご理解いただきありがとうございます。",
"educationDiscountPaused.title": "教育割引は一時停止中です",
"educationPricingConfirm.cancel": "現在のプランを維持",
"educationPricingConfirm.continue": "Professional 年間プランに切り替える",
"educationPricingConfirm.description": "教育割引は Professional 年間プランにのみ適用されます。現在のプランを維持すると、割引は適用されません。",
@@ -23,6 +27,7 @@
"form.terms.desc.termsOfService": "利用規約",
"form.terms.option.age": "18 歳以上であることを確認します。",
"form.terms.option.inSchool": "提供した教育機関に在籍または勤務している ことを確認します。Dify は在籍/雇用証明の提出を求める場合があります。不正な情報を申告した場合、教育認証に基づき免除された費用を支払うことに同意します。",
"form.terms.option.personalUse": "Education Verified ステータスおよび割引、クーポン、クレジットを含むすべての関連特典は、私個人の利用のみを目的とすることを確認します。これらを第三者に販売、譲渡、共有、再許諾したり、Dify サービスへの有料アクセスを第三者に提供するために使用したりしません。",
"form.terms.title": "利用規約と同意事項",
"learn": "教育認証の取得方法はこちら",
"notice.action.dismiss": "無視",
+5
View File
@@ -5,6 +5,10 @@
"applied.step1.description": "교육 할인 신청이 성공적으로 완료되었습니다.",
"applied.step2.description": "교육 할인을 사용할 워크스페이스를 선택하세요.",
"currentSigned": "현재 로그인 중입니다",
"educationDiscountPaused.description": "최근 의심스러운 신청과 오용이 증가함에 따라 보안 조치를 강화하는 동안 신규 신청과 할인 사용을 일시 중단했습니다.",
"educationDiscountPaused.publishedAt": "2026년 8월 10일 게시",
"educationDiscountPaused.thanks": "양해해 주셔서 감사합니다.",
"educationDiscountPaused.title": "교육 할인이 일시 중단되었습니다",
"educationPricingConfirm.cancel": "현재 플랜 유지",
"educationPricingConfirm.continue": "Professional 연간으로 전환",
"educationPricingConfirm.description": "교육 할인은 Professional 연간 플랜에만 적용됩니다. 현재 플랜을 유지하면 할인이 포함되지 않습니다.",
@@ -23,6 +27,7 @@
"form.terms.desc.termsOfService": "서비스 약관",
"form.terms.option.age": "만 18세 이상입니다.",
"form.terms.option.inSchool": "나는 제공된 기관에 재학 중이거나 고용되어 있음을 확인합니다. Dify 는 재학증명서나 고용증명서를 요청할 수 있습니다. 만약 내가 자격을 허위로 진술하면, 나는 내 교육 상태에 따라 처음 면제된 수수료를 지불하기로 동의합니다.",
"form.terms.option.personalUse": "본인의 Education Verified 상태와 할인, 쿠폰, 크레딧을 포함한 모든 관련 혜택은 본인의 개인적인 용도로만 사용됨을 확인합니다. 이를 제3자에게 판매, 양도, 공유 또는 재라이선스하거나 제3자에게 Dify 서비스의 유료 액세스를 제공하는 데 사용하지 않겠습니다.",
"form.terms.title": "약관 및 동의사항",
"learn": "교육 인증을 받는 방법을 배우세요",
"notice.action.dismiss": "해제",
+5
View File
@@ -5,6 +5,10 @@
"applied.step1.description": "ທ່ານໄດ້ສະໝັກຂໍສ່ວນຫຼຸດເພື່ອການສຶກສາສຳເລັດແລ້ວ.",
"applied.step2.description": "ເລືອກພື້ນທີ່ເຮັດວຽກທີ່ທ່ານຕ້ອງການໃຊ້ສ່ວນຫຼຸດເພື່ອການສຶກສາ.",
"currentSigned": "ເຂົ້າສູ່ລະບົບໃນປັດຈຸບັນໃນນາມ",
"educationDiscountPaused.description": "ເນື່ອງຈາກມີການສະໝັກທີ່ໜ້າສົງໄສ ແລະ ການນຳໃຊ້ໃນທາງທີ່ຜິດເພີ່ມຂຶ້ນໃນໄລຍະຫຼ້ານີ້, ພວກເຮົາໄດ້ຢຸດການສະໝັກໃໝ່ ແລະ ການໃຊ້ສ່ວນຫຼຸດໄວ້ຊົ່ວຄາວ ໃນຂະນະທີ່ປັບປຸງມາດຕະການຄວາມປອດໄພ.",
"educationDiscountPaused.publishedAt": "ເຜີຍແຜ່ວັນທີ 10 ສິງຫາ 2026",
"educationDiscountPaused.thanks": "ຂອບໃຈສຳລັບຄວາມເຂົ້າໃຈຂອງທ່ານ.",
"educationDiscountPaused.title": "ສ່ວນຫຼຸດການສຶກສາຖືກຢຸດໄວ້ຊົ່ວຄາວ",
"educationPricingConfirm.cancel": "ໃຊ້ແພັກເກດປັດຈຸບັນຕໍ່ໄປ",
"educationPricingConfirm.continue": "ປ່ຽນເປັນ Professional ແບບລາຍປີ",
"educationPricingConfirm.description": "ສ່ວນຫຼຸດເພື່ອການສຶກສານຳໃຊ້ໄດ້ກັບແພັກເກດ Professional ແບບລາຍປີເທົັ້ນັ້ນ. ການໃຊ້ແພັກເກດປັດຈຸບັນຂອງທ່ານຕໍ່ໄປຈະບໍ່ລວມເອົາສ່ວນຫຼຸດນີ້.",
@@ -23,6 +27,7 @@
"form.terms.desc.termsOfService": "ເງື່ອນໄຂການບໍລິການ",
"form.terms.option.age": "ຂ້ອຍຢືນຢັນວ່າຂ້ອຍມີອາຍຸຢ່າງໜ້ອຍ 18 ປີ",
"form.terms.option.inSchool": "ຂ້ອຍຢືນຢັນວ່າຂ້ອຍກຳລັງສຶກສາ ຫຼື ເຮັດວຽກຢູ່ສະຖາບັນທີ່ລະບຸໄວ້. Dify ອາດຈະຂໍຫຼັກຖານການສຶກສາ/ການເຮັດວຽກ. ຫາກຂ້ອຍໃຫ້ຂໍ້ມູນບໍ່ຖືກຕ້ອງກ່ຽວກັບຄຸນສົມບັດຂອງຕົນເອງ, ຂ້ອຍຕົກລົງທີ່ຈະຊຳລະຄ່າທຳນຽມຕ່າງໆ ທີ່ໄດ້ຮັບການຍົກເວັ້ນໃນເບື້ອງຕົ້ນຕາມສະຖານະການສຶກສາຂອງຂ້ອຍ.",
"form.terms.option.personalUse": "ຂ້ອຍຢືນຢັນວ່າສະຖານະ Education Verified ຂອງຂ້ອຍ ແລະ ສິດປະໂຫຍດທີ່ກ່ຽວຂ້ອງທັງໝົດ ລວມທັງສ່ວນຫຼຸດ, ຄູປອງ ແລະ ເຄຣດິດ ແມ່ນສຳລັບການນຳໃຊ້ສ່ວນຕົວຂອງຂ້ອຍເທົ່ານັ້ນ. ຂ້ອຍຈະບໍ່ຂາຍ, ໂອນ, ແບ່ງປັນ, ອະນຸຍາດຊ່ວງ ຫຼື ນຳໃຊ້ສິດເຫຼົ່ານີ້ເພື່ອໃຫ້ບຸກຄົນທີສາມເຂົ້າເຖິງບໍລິການ Dify ແບບເສຍຄ່າ.",
"form.terms.title": "ຂໍ້ກຳນົດ ແລະ ຂໍ້ຕົກລົງ",
"learn": "ຮຽນຮູ້ວິທີການຢືນຢັນສະຖານະເພື່ອການສຶກສາ",
"notice.action.dismiss": "ປິດອອກ",
+5
View File
@@ -5,6 +5,10 @@
"applied.step1.description": "U heeft met succes de onderwijskorting aangevraagd.",
"applied.step2.description": "Selecteer de werkruimte die u wilt gebruiken met de onderwijskorting.",
"currentSigned": "CURRENTLY SIGNED IN AS",
"educationDiscountPaused.description": "Door een recente toename van verdachte aanvragen en misbruik hebben we nieuwe aanvragen en verzilveringen tijdelijk gepauzeerd terwijl we onze beveiligingsmaatregelen verbeteren.",
"educationDiscountPaused.publishedAt": "Gepubliceerd op 10 augustus 2026",
"educationDiscountPaused.thanks": "Bedankt voor uw begrip.",
"educationDiscountPaused.title": "Onderwijskorting tijdelijk gepauzeerd",
"educationPricingConfirm.cancel": "Huidig abonnement behouden",
"educationPricingConfirm.continue": "Overschakelen naar Professional jaarlijks",
"educationPricingConfirm.description": "De onderwijskorting is alleen van toepassing op het jaarlijkse Professional-abonnement. Als u uw huidige abonnement behoudt, is de korting niet inbegrepen.",
@@ -23,6 +27,7 @@
"form.terms.desc.termsOfService": "Terms of Service",
"form.terms.option.age": "I confirm I am at least 18 years old",
"form.terms.option.inSchool": "I confirm I am enrolled or employed at the institution provided. Dify may request proof of enrollment/employment. If I misrepresent my eligibility, I agree to pay any fees initially waived based on my education status.",
"form.terms.option.personalUse": "Ik bevestig dat mijn Education Verified-status en alle bijbehorende voordelen, waaronder kortingen, coupons en tegoeden, uitsluitend voor persoonlijk gebruik zijn. Ik zal deze niet verkopen, overdragen, delen, in sublicentie geven of gebruiken om derden tegen betaling toegang te bieden tot Dify-services.",
"form.terms.title": "Terms & Agreements",
"learn": "Learn how to get education verified",
"notice.action.dismiss": "Dismiss",
+5
View File
@@ -5,6 +5,10 @@
"applied.step1.description": "Pomyślnie złożono wniosek o rabat edukacyjny.",
"applied.step2.description": "Wybierz obszar roboczy, który chcesz używać z rabatem edukacyjnym.",
"currentSigned": "AKTUALNIE ZALOGOWANY JAKO",
"educationDiscountPaused.description": "Ze względu na niedawny wzrost liczby podejrzanych zgłoszeń i nadużyć tymczasowo wstrzymaliśmy nowe zgłoszenia i realizację zniżek na czas ulepszania naszych zabezpieczeń.",
"educationDiscountPaused.publishedAt": "Opublikowano 10 sierpnia 2026 r.",
"educationDiscountPaused.thanks": "Dziękujemy za wyrozumiałość.",
"educationDiscountPaused.title": "Zniżka edukacyjna tymczasowo wstrzymana",
"educationPricingConfirm.cancel": "Zachowaj obecny plan",
"educationPricingConfirm.continue": "Przełącz na Professional roczny",
"educationPricingConfirm.description": "Zniżka edukacyjna dotyczy tylko rocznego planu Professional. Pozostanie przy obecnym planie nie obejmie zniżki.",
@@ -23,6 +27,7 @@
"form.terms.desc.termsOfService": "Warunki świadczenia usług",
"form.terms.option.age": "Potwierdzam, że mam co najmniej 18 lat",
"form.terms.option.inSchool": "Potwierdzam, że jestem zapisany lub zatrudniony w podanej instytucji. Dify może wymagać dowodu zapisania/zatrudnienia. Jeśli wprowadzę w błąd dotyczący mojej zdolności do uczestnictwa, zgadzam się zapłacić wszelkie opłaty, które zostały początkowo zaniechane w oparciu o mój status edukacyjny.",
"form.terms.option.personalUse": "Potwierdzam, że mój status Education Verified i wszystkie powiązane korzyści, w tym rabaty, kupony i środki, są przeznaczone wyłącznie do mojego osobistego użytku. Nie będę ich sprzedawać, przekazywać, udostępniać, udzielać na nie sublicencji ani wykorzystywać ich do zapewniania osobom trzecim płatnego dostępu do usług Dify.",
"form.terms.title": "Warunki i umowy",
"learn": "Dowiedz się, jak uzyskać potwierdzenie wykształcenia",
"notice.action.dismiss": "Odrzuć",
+5
View File
@@ -5,6 +5,10 @@
"applied.step1.description": "Você solicitou com sucesso o desconto educacional.",
"applied.step2.description": "Selecione o workspace que deseja usar com o desconto educacional.",
"currentSigned": "ATUALMENTE CONECTADO COMO",
"educationDiscountPaused.description": "Devido ao recente aumento de solicitações suspeitas e uso indevido, pausamos temporariamente novas solicitações e resgates enquanto aprimoramos nossas medidas de segurança.",
"educationDiscountPaused.publishedAt": "Publicado em 10 de agosto de 2026",
"educationDiscountPaused.thanks": "Agradecemos a sua compreensão.",
"educationDiscountPaused.title": "Desconto educacional temporariamente pausado",
"educationPricingConfirm.cancel": "Manter plano atual",
"educationPricingConfirm.continue": "Mudar para Professional anual",
"educationPricingConfirm.description": "O desconto educacional se aplica apenas ao plano Professional anual. Manter seu plano atual não incluirá o desconto.",
@@ -23,6 +27,7 @@
"form.terms.desc.termsOfService": "Termos de Serviço",
"form.terms.option.age": "Eu confirmo que tenho pelo menos 18 anos",
"form.terms.option.inSchool": "Eu confirmo que estou matriculado ou empregado na instituição mencionada. A Dify pode solicitar comprovação de matrícula/emprego. Se eu representar indevidamente minha elegibilidade, concordo em pagar quaisquer taxas inicialmente isentas com base no meu status educacional.",
"form.terms.option.personalUse": "Confirmo que meu status Education Verified e todos os benefícios associados, incluindo descontos, cupons e créditos, são exclusivamente para meu uso pessoal. Não os venderei, transferirei, compartilharei, sublicenciarei nem os utilizarei para fornecer a terceiros acesso pago aos serviços da Dify.",
"form.terms.title": "Termos e Acordos",
"learn": "Aprenda como fazer a verificação da sua educação",
"notice.action.dismiss": "Dispensar",
+5
View File
@@ -5,6 +5,10 @@
"applied.step1.description": "Ai aplicat cu succes pentru reducerea educațională.",
"applied.step2.description": "Selectează workspace-ul pe care dorești să-l utilizezi cu reducerea educațională.",
"currentSigned": "CONEXIUNE ÎN PREZENT CA",
"educationDiscountPaused.description": "Din cauza creșterii recente a numărului de solicitări suspecte și a utilizării abuzive, am suspendat temporar solicitările noi și valorificarea reducerilor până când ne îmbunătățim măsurile de securitate.",
"educationDiscountPaused.publishedAt": "Publicat la 10 august 2026",
"educationDiscountPaused.thanks": "Vă mulțumim pentru înțelegere.",
"educationDiscountPaused.title": "Reducerea pentru educație este suspendată temporar",
"educationPricingConfirm.cancel": "Păstrează planul curent",
"educationPricingConfirm.continue": "Treci la Professional anual",
"educationPricingConfirm.description": "Reducerea educațională se aplică doar planului Professional anual. Dacă păstrezi planul curent, reducerea nu va fi inclusă.",
@@ -23,6 +27,7 @@
"form.terms.desc.termsOfService": "Termeni și condiții",
"form.terms.option.age": "Confirm că am cel puțin 18 ani",
"form.terms.option.inSchool": "Confirm că sunt înscris sau angajat la instituția menționată. Dify poate solicita dovada înscrierii/angajării. Dacă îmi reprezint greșit eligibilitatea, sunt de acord să plătesc orice taxe inițial renunțate pe baza statutului meu educațional.",
"form.terms.option.personalUse": "Confirm că statutul meu Education Verified și toate beneficiile asociate, inclusiv reducerile, cupoanele și creditele, sunt destinate exclusiv uzului meu personal. Nu le voi vinde, transfera, partaja, sublicenția și nu le voi utiliza pentru a oferi vreunei terțe părți acces plătit la serviciile Dify.",
"form.terms.title": "Termeni și condiții",
"learn": "Învățați cum să verificați educația",
"notice.action.dismiss": "Respingere",
+5
View File
@@ -5,6 +5,10 @@
"applied.step1.description": "Вы успешно подали заявку на образовательную скидку.",
"applied.step2.description": "Выберите рабочее пространство, которое хотите использовать с образовательной скидкой.",
"currentSigned": "В ДАННЫЙ МОМЕНТ ВХОД В ПРОФИЛЬ КАК",
"educationDiscountPaused.description": "Из-за недавнего роста числа подозрительных заявок и случаев злоупотребления мы временно приостановили прием новых заявок и использование скидок, пока совершенствуем меры безопасности.",
"educationDiscountPaused.publishedAt": "Опубликовано 10 августа 2026 г.",
"educationDiscountPaused.thanks": "Благодарим за понимание.",
"educationDiscountPaused.title": "Образовательная скидка временно приостановлена",
"educationPricingConfirm.cancel": "Оставить текущий план",
"educationPricingConfirm.continue": "Перейти на Professional годовой",
"educationPricingConfirm.description": "Образовательная скидка применяется только к годовому плану Professional. Если оставить текущий план, скидка не будет включена.",
@@ -23,6 +27,7 @@
"form.terms.desc.termsOfService": "Условия обслуживания",
"form.terms.option.age": "Я подтверждаю, что мне не меньше 18 лет",
"form.terms.option.inSchool": "Я подтверждаю, что я зачислен или работаю в указанной учреждении. Dify может запросить подтверждение зачисления/трудоустройства. Если я неправильно укажу свою правообладанность, я согласен оплатить любые сборы, которые изначально были отменены на основании моего образовательного статуса.",
"form.terms.option.personalUse": "Я подтверждаю, что мой статус Education Verified и все связанные с ним преимущества, включая скидки, купоны и кредиты, предназначены исключительно для моего личного использования. Я не буду продавать, передавать, делиться, сублицензировать их или использовать для предоставления третьим лицам платного доступа к сервисам Dify.",
"form.terms.title": "Условия и соглашения",
"learn": "Узнайте, как получить подтверждение образования",
"notice.action.dismiss": "Отклонить",
+5
View File
@@ -5,6 +5,10 @@
"applied.step1.description": "Uspešno ste se prijavili za izobraževalni popust.",
"applied.step2.description": "Izberite delovni prostor, ki ga želite uporabiti z izobraževalnim popustom.",
"currentSigned": "Trenutno prijavljen kot",
"educationDiscountPaused.description": "Zaradi nedavnega povečanja števila sumljivih prijav in zlorab smo začasno ustavili nove prijave in unovčitve popustov, medtem ko nadgrajujemo varnostne ukrepe.",
"educationDiscountPaused.publishedAt": "Objavljeno 10. avgusta 2026",
"educationDiscountPaused.thanks": "Hvala za razumevanje.",
"educationDiscountPaused.title": "Izobraževalni popust je začasno ustavljen",
"educationPricingConfirm.cancel": "Obdrži trenutni paket",
"educationPricingConfirm.continue": "Preklopi na letni Professional",
"educationPricingConfirm.description": "Izobraževalni popust velja samo za letni paket Professional. Če obdržite trenutni paket, popust ne bo vključen.",
@@ -23,6 +27,7 @@
"form.terms.desc.termsOfService": "Pogoji storitve",
"form.terms.option.age": "Potrjujem, da sem star najmanj 18 let",
"form.terms.option.inSchool": "Potrjujem, da sem vpisan ali zaposlen na navedenem zavodu. Dify lahko zahteva dokazilo o vpisu/zaposlitvi. Če napačno predstavim svojo upravičenost, se strinjam, da plačam morebitne pristojbine, ki so bile sprva oproščene na podlagi mojega izobraževalnega statusa.",
"form.terms.option.personalUse": "Potrjujem, da so moj status Education Verified in vse povezane ugodnosti, vključno s popusti, kuponi in dobroimetjem, namenjeni izključno moji osebni uporabi. Ne bom jih prodajal, prenašal, delil, podlicenciral ali uporabljal za zagotavljanje plačljivega dostopa do storitev Dify tretjim osebam.",
"form.terms.title": "Pogoji in dogovori",
"learn": "Naučite se, kako preveriti izobrazbo",
"notice.action.dismiss": "Odpusti",
+5
View File
@@ -5,6 +5,10 @@
"applied.step1.description": "คุณได้สมัครรับส่วนลดการศึกษาสำเร็จแล้ว",
"applied.step2.description": "เลือกพื้นที่ทำงานที่คุณต้องการใช้กับส่วนลดการศึกษา",
"currentSigned": "ลงชื่อเข้าใช้ในฐานะ",
"educationDiscountPaused.description": "เนื่องจากมีการสมัครที่น่าสงสัยและการใช้งานในทางที่ผิดเพิ่มขึ้นในช่วงที่ผ่านมา เราจึงหยุดรับสมัครใหม่และการแลกรับส่วนลดไว้ชั่วคราวระหว่างที่ปรับปรุงมาตรการรักษาความปลอดภัย",
"educationDiscountPaused.publishedAt": "เผยแพร่เมื่อ 10 สิงหาคม 2026",
"educationDiscountPaused.thanks": "ขอขอบคุณสำหรับความเข้าใจ",
"educationDiscountPaused.title": "ส่วนลดเพื่อการศึกษาหยุดให้บริการชั่วคราว",
"educationPricingConfirm.cancel": "ใช้แผนปัจจุบันต่อ",
"educationPricingConfirm.continue": "เปลี่ยนเป็น Professional รายปี",
"educationPricingConfirm.description": "ส่วนลดการศึกษาใช้ได้เฉพาะกับแผน Professional รายปีเท่านั้น หากใช้แผนปัจจุบันต่อ จะไม่มีส่วนลดนี้รวมอยู่ด้วย",
@@ -23,6 +27,7 @@
"form.terms.desc.termsOfService": "ข้อกำหนดในการให้บริการ",
"form.terms.option.age": "ฉันยืนยันว่าฉันมีอายุอย่างน้อย 18 ปี",
"form.terms.option.inSchool": "ฉันยืนยันว่าฉันได้ลงทะเบียนหรือทำงานที่สถาบันที่ระบุไว้ Dify อาจขอหลักฐานการลงทะเบียน/การจ้างงาน หากฉันแสดงความไม่ถูกต้องเกี่ยวกับคุณสมบัติของฉัน ฉันตกลงที่จะชำระค่าธรรมเนียมใด ๆ ที่ถูกยกเว้นไปในเบื้องต้นตามสถานะการศึกษาของฉัน.",
"form.terms.option.personalUse": "ฉันยืนยันว่าสถานะ Education Verified ของฉันและสิทธิประโยชน์ที่เกี่ยวข้องทั้งหมด รวมถึงส่วนลด คูปอง และเครดิต มีไว้สำหรับการใช้งานส่วนตัวของฉันเท่านั้น ฉันจะไม่ขาย โอน แบ่งปัน ให้สิทธิ์ช่วง หรือใช้สิทธิประโยชน์เหล่านี้เพื่อให้บุคคลที่สามเข้าถึงบริการ Dify แบบชำระเงิน",
"form.terms.title": "ข้อกำหนดและเงื่อนไข",
"learn": "เรียนรู้วิธีการตรวจสอบการศึกษา",
"notice.action.dismiss": "ปฏิเสธ",
+5
View File
@@ -5,6 +5,10 @@
"applied.step1.description": "Eğitim indirimi için başarıyla başvurdunuz.",
"applied.step2.description": "Eğitim indirimiyle kullanmak istediğiniz çalışma alanını seçin.",
"currentSigned": "ŞU ANDA GİRİŞ YAPILDIĞI KİŞİ",
"educationDiscountPaused.description": "Şüpheli başvuruların ve kötüye kullanımın son dönemde artması nedeniyle, güvenlik önlemlerimizi geliştirirken yeni başvuruları ve indirim kullanımlarını geçici olarak duraklattık.",
"educationDiscountPaused.publishedAt": "10 Ağustos 2026'da yayımlandı",
"educationDiscountPaused.thanks": "Anlayışınız için teşekkür ederiz.",
"educationDiscountPaused.title": "Eğitim indirimi geçici olarak duraklatıldı",
"educationPricingConfirm.cancel": "Mevcut planı koru",
"educationPricingConfirm.continue": "Professional yıllık plana geç",
"educationPricingConfirm.description": "Eğitim indirimi yalnızca yıllık Professional planı için geçerlidir. Mevcut planınızı korursanız indirim dahil edilmez.",
@@ -23,6 +27,7 @@
"form.terms.desc.termsOfService": "Hizmet Şartları",
"form.terms.option.age": "En az 18 yaşında olduğumu onaylıyorum.",
"form.terms.option.inSchool": "Verilen kurumda kayıtlı veya istihdamda olduğumu onaylıyorum. Dify, kayıt veya istihdam kanıtı talep edebilir. Uygunluğumu yanlış beyan edersem, eğitim durumuma dayalı olarak başlangıçta feragat edilen her türlü ücreti ödemeyi kabul ediyorum.",
"form.terms.option.personalUse": "Education Verified durumumun ve indirimler, kuponlar ve krediler dahil ilgili tüm avantajların yalnızca kişisel kullanımım için olduğunu onaylıyorum. Bunları üçüncü taraflara satmayacak, devretmeyecek, paylaşmayacak, alt lisans vermeyecek veya Dify hizmetlerine ücretli erişim sağlamak için kullanmayacağım.",
"form.terms.title": "Şartlar ve Koşullar",
"learn": "Eğitim doğrulamasının nasıl yapılacağını öğrenin",
"notice.action.dismiss": "Reddet",
+5
View File
@@ -5,6 +5,10 @@
"applied.step1.description": "Ви успішно подали заявку на освітню знижку.",
"applied.step2.description": "Виберіть робочий простір, який ви хочете використовувати з освітньою знижкою.",
"currentSigned": "В даний момент ви підписані як",
"educationDiscountPaused.description": "Через нещодавнє зростання кількості підозрілих заявок і випадків зловживання ми тимчасово призупинили прийом нових заявок і використання знижок, поки вдосконалюємо заходи безпеки.",
"educationDiscountPaused.publishedAt": "Опубліковано 10 серпня 2026 року",
"educationDiscountPaused.thanks": "Дякуємо за розуміння.",
"educationDiscountPaused.title": "Освітню знижку тимчасово призупинено",
"educationPricingConfirm.cancel": "Залишити поточний план",
"educationPricingConfirm.continue": "Перейти на Professional річний",
"educationPricingConfirm.description": "Освітня знижка застосовується лише до річного плану Professional. Якщо залишити поточний план, знижку не буде включено.",
@@ -23,6 +27,7 @@
"form.terms.desc.termsOfService": "Умови обслуговування",
"form.terms.option.age": "Я підтверджую, що мені щонайменше 18 років.",
"form.terms.option.inSchool": "Я підтверджую, що я зареєстрований або працюю в зазначеній установі. Dify може вимагати підтвердження моєї реєстрації/трудової зайнятості. Якщо я неправильно представлю свою кваліфікацію, я погоджуюся сплатити будь-які збори, які спочатку були скасовані на основі мого навчального статусу.",
"form.terms.option.personalUse": "Я підтверджую, що мій статус Education Verified і всі пов’язані з ним переваги, зокрема знижки, купони та кредити, призначені виключно для мого особистого використання. Я не продаватиму, не передаватиму, не поширюватиму, не надаватиму субліцензії та не використовуватиму їх для надання третім особам платного доступу до сервісів Dify.",
"form.terms.title": "Умови та угоди",
"learn": "Дізнайтеся, як перевірити освіту",
"notice.action.dismiss": "Відхилити",
+5
View File
@@ -5,6 +5,10 @@
"applied.step1.description": "Bạn đã đăng ký giảm giá giáo dục thành công.",
"applied.step2.description": "Chọn workspace bạn muốn sử dụng với giảm giá giáo dục.",
"currentSigned": "HIỆN ĐANG ĐĂNG NHẬP VÀO",
"educationDiscountPaused.description": "Do số lượng đơn đăng ký đáng ngờ và hành vi lạm dụng gần đây gia tăng, chúng tôi đã tạm dừng các đơn đăng ký mới và việc sử dụng ưu đãi trong khi nâng cấp các biện pháp bảo mật.",
"educationDiscountPaused.publishedAt": "Đăng ngày 10 tháng 8 năm 2026",
"educationDiscountPaused.thanks": "Cảm ơn bạn đã thông cảm.",
"educationDiscountPaused.title": "Ưu đãi giáo dục tạm thời bị tạm dừng",
"educationPricingConfirm.cancel": "Giữ gói hiện tại",
"educationPricingConfirm.continue": "Chuyển sang Professional hằng năm",
"educationPricingConfirm.description": "Giảm giá giáo dục chỉ áp dụng cho gói Professional hằng năm. Nếu giữ gói hiện tại, giảm giá sẽ không được áp dụng.",
@@ -23,6 +27,7 @@
"form.terms.desc.termsOfService": "Điều khoản dịch vụ",
"form.terms.option.age": "Tôi xác nhận rằng tôi ít nhất 18 tuổi",
"form.terms.option.inSchool": "Tôi xác nhận rằng tôi đã đăng ký hoặc làm việc tại cơ sở đã cung cấp. Dify có thể yêu cầu chứng minh về việc đăng ký/làm việc. Nếu tôi cung cấp thông tin không chính xác về đủ điều kiện của mình, tôi đồng ý trả bất kỳ khoản phí nào ban đầu được miễn dựa trên tình trạng giáo dục của tôi.",
"form.terms.option.personalUse": "Tôi xác nhận rằng trạng thái Education Verified của tôi và tất cả quyền lợi liên quan, bao gồm giảm giá, phiếu ưu đãi và tín dụng, chỉ dành cho mục đích sử dụng cá nhân của tôi. Tôi sẽ không bán, chuyển nhượng, chia sẻ, cấp phép lại hoặc sử dụng các quyền lợi này để cung cấp quyền truy cập trả phí vào các dịch vụ Dify cho bất kỳ bên thứ ba nào.",
"form.terms.title": "Điều khoản & Thỏa thuận",
"learn": "Học cách xác minh trình độ giáo dục",
"notice.action.dismiss": "Bỏ qua",
+5
View File
@@ -5,6 +5,10 @@
"applied.step1.description": "您已成功申请教育优惠。",
"applied.step2.description": "选择要使用教育优惠的 workspace。",
"currentSigned": "您当前登录的账户是",
"educationDiscountPaused.description": "由于近期可疑申请和滥用行为有所增加,我们在升级安全措施期间,暂时停止接受新的申请及优惠兑换。",
"educationDiscountPaused.publishedAt": "发布于 2026 年 8 月 10 日",
"educationDiscountPaused.thanks": "感谢您的理解。",
"educationDiscountPaused.title": "教育优惠暂时停止",
"educationPricingConfirm.cancel": "保留当前计划",
"educationPricingConfirm.continue": "切换到 Professional 年付",
"educationPricingConfirm.description": "教育优惠仅适用于 Professional 年付计划。保留当前计划将不包含该优惠。",
@@ -23,6 +27,7 @@
"form.terms.desc.termsOfService": "服务条款",
"form.terms.option.age": "我确认我已年满 18 周岁。",
"form.terms.option.inSchool": "我确认我目前已在提供的学校入学或受雇。Dify 可能会要求提供入学/雇佣证明。如我虚报资格,我同意支付因教育版认证而被减免的费用。",
"form.terms.option.personalUse": "我确认,我的 Education Verified 身份及其所有相关权益(包括折扣、优惠券和额度)仅供本人使用。我不会出售、转让、共享、再许可这些权益,也不会利用它们向任何第三方提供 Dify 服务的付费访问权限。",
"form.terms.title": "条款与协议",
"learn": "了解如何获取教育版认证",
"notice.action.dismiss": "忽略",
+5
View File
@@ -5,6 +5,10 @@
"applied.step1.description": "您已成功申請教育優惠。",
"applied.step2.description": "選擇要使用教育優惠的 workspace。",
"currentSigned": "當前以以下身份登入",
"educationDiscountPaused.description": "由於近期可疑申請和濫用行為有所增加,我們在升級安全措施期間,暫時停止接受新的申請及優惠兌換。",
"educationDiscountPaused.publishedAt": "發布於 2026 年 8 月 10 日",
"educationDiscountPaused.thanks": "感謝您的理解。",
"educationDiscountPaused.title": "教育優惠暫時停止",
"educationPricingConfirm.cancel": "保留目前方案",
"educationPricingConfirm.continue": "切換到 Professional 年付",
"educationPricingConfirm.description": "教育優惠僅適用於 Professional 年付方案。保留目前方案將不包含此優惠。",
@@ -23,6 +27,7 @@
"form.terms.desc.termsOfService": "服務條款",
"form.terms.option.age": "我確認我至少 18 歲",
"form.terms.option.inSchool": "我確認我已在所提供的機構註冊或受僱。Dify 可能會要求提供註冊/就業的證明。如果我錯誤表述我的資格,我同意支付根據我的教育狀況最初免除的任何費用。",
"form.terms.option.personalUse": "我確認,我的 Education Verified 身分及其所有相關權益(包括折扣、優惠券和額度)僅供本人使用。我不會出售、轉讓、分享、再授權這些權益,也不會利用它們向任何第三方提供 Dify 服務的付費存取權限。",
"form.terms.title": "條款與協議",
"learn": "了解如何進行教育驗證",
"notice.action.dismiss": "解散",