Bezahlseite erscheint in der Sprache des Nutzers

Wer von der tuerkischen Seite kam, landete bisher auf einer deutschen
Stripe-Seite — fuer die Zielgruppe die groesste Huerde im Kaufvorgang.

/kaufen nimmt jetzt 'sprache' entgegen und gibt sie als locale an Stripe
weiter. Nur Sprachen aus STRIPE_SPRACHEN werden geschickt: Ein unbekannter
Wert laesst Stripe die Session mit 400 ablehnen, der Kauf waere kaputt. Fuer
Arabisch, Tigrinya usw. (kennt Stripe nicht) wird nichts mitgeschickt, dann
waehlt Stripe selbst anhand des Browsers.

Alle drei Kauf-Stellen geben die Sprache mit: Sprachseiten fest ihre eigene,
Demo-Seite die dort gewaehlte Zielsprache, Startseite 'de'.

Geprueft: tr/de/pl/ar liefern Bezahlseiten, und eine erfundene Sprache faellt
sauber zurueck statt den Kauf zu brechen.

Stripe Link (die vorausgewaehlte Schnellzahlung) laesst sich NICHT per API
abschalten — laut Stripe-Docs nur in den Zahlungsmethoden-Einstellungen des
Dashboards.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
JUSNandClaude Opus 5 committed 2026-09-23 15:59:46 +02:00
1 parent e5915f3cc2
commit 585f027ba5
33 files changed
+76 -59

No files matched your search

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

+18 -1
View File
@@ -477,13 +477,26 @@ async function guthabenMail(env: Env, email: string, link: string, credits: numb
}
/** POST /kaufen — Stripe-Checkout-Session anlegen. */
/**
* Sprachen, die die Stripe-Bezahlseite selbst beherrscht. Nur diese duerfen
* als `locale` mitgegeben werden — ein unbekannter Wert laesst Stripe die
* Session mit 400 ablehnen, und der Kauf waere kaputt. Fehlt eine Sprache
* hier (z. B. Arabisch, Tigrinya), schicken wir GAR NICHTS mit; Stripe
* waehlt dann selbst anhand des Browsers.
*/
const STRIPE_SPRACHEN = new Set([
'bg','cs','da','de','el','en','es','et','fi','fil','fr','hr','hu','id','it',
'ja','ko','lt','lv','ms','mt','nb','nl','pl','pt','ro','ru','sk','sl','sv',
'th','tr','vi','zh',
]);
async function kaufenHandler(request: Request, env: Env): Promise<Response> {
const origin = request.headers.get('origin');
if (request.method === 'OPTIONS') return new Response(null, { status: 204, headers: demoCorsHeaders(origin) });
if (request.method !== 'POST') return demoFehler(405, 'methode', 'Nur POST erlaubt.', origin);
if (!origin || !DEMO_ORIGIN_MUSTER.test(origin)) return demoFehler(403, 'origin', 'Aufruf nur von der BehördenKlar-Webseite erlaubt.', origin);
let body: { priceId?: string };
let body: { priceId?: string; sprache?: string };
try {
body = await request.json();
} catch {
@@ -503,6 +516,10 @@ async function kaufenHandler(request: Request, env: Env): Promise<Response> {
params.set('metadata[walletId]', walletId);
params.set('metadata[credits]', String(paket.credits));
params.set('metadata[origin]', origin);
// Bezahlseite in der Sprache zeigen, aus der der Nutzer kommt.
if (typeof body.sprache === 'string' && STRIPE_SPRACHEN.has(body.sprache)) {
params.set('locale', body.sprache);
}
const r = await fetch('https://api.stripe.com/v1/checkout/sessions', {
method: 'POST',
+1 -1
View File
@@ -252,7 +252,7 @@
if (!konsens.checked) { fehler.style.display = 'block'; fehler.textContent = '{{KAUF_FEHLER_HAKEN}}'; konsens.focus(); return; }
fehler.style.display = 'none';
var alt = knopf.innerHTML; knopf.disabled = true;
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId }) })
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId, sprache: '{{LANG}}' }) })
.then(function (r) { return r.json(); })
.then(function (d) { if (d && d.url) { window.location.href = d.url; return; } throw new Error('x'); })
.catch(function () { knopf.disabled = false; knopf.innerHTML = alt; fehler.style.display = 'block'; fehler.textContent = '{{KAUF_FEHLER_ALLG}}'; });
+1 -1
View File
@@ -407,7 +407,7 @@
if (!konsens.checked) { fehler.style.display = 'block'; fehler.textContent = 'يرجى تأكيد المربع أولاً.'; konsens.focus(); return; }
fehler.style.display = 'none';
var alt = knopf.innerHTML; knopf.disabled = true;
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId }) })
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId, sprache: 'ar' }) })
.then(function (r) { return r.json(); })
.then(function (d) { if (d && d.url) { window.location.href = d.url; return; } throw new Error('x'); })
.catch(function () { knopf.disabled = false; knopf.innerHTML = alt; fehler.style.display = 'block'; fehler.textContent = 'تعذّر فتح صفحة الدفع. يرجى المحاولة مرة أخرى.'; });
+1 -1
View File
@@ -407,7 +407,7 @@
if (!konsens.checked) { fehler.style.display = 'block'; fehler.textContent = 'Моля, първо отбележете полето.'; konsens.focus(); return; }
fehler.style.display = 'none';
var alt = knopf.innerHTML; knopf.disabled = true;
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId }) })
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId, sprache: 'bg' }) })
.then(function (r) { return r.json(); })
.then(function (d) { if (d && d.url) { window.location.href = d.url; return; } throw new Error('x'); })
.catch(function () { knopf.disabled = false; knopf.innerHTML = alt; fehler.style.display = 'block'; fehler.textContent = 'Страницата за плащане не можа да се отвори. Опитайте отново.'; });
+1 -1
View File
@@ -407,7 +407,7 @@
if (!konsens.checked) { fehler.style.display = 'block'; fehler.textContent = 'Molimo najprije označite polje.'; konsens.focus(); return; }
fehler.style.display = 'none';
var alt = knopf.innerHTML; knopf.disabled = true;
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId }) })
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId, sprache: 'bs' }) })
.then(function (r) { return r.json(); })
.then(function (d) { if (d && d.url) { window.location.href = d.url; return; } throw new Error('x'); })
.catch(function () { knopf.disabled = false; knopf.innerHTML = alt; fehler.style.display = 'block'; fehler.textContent = 'Stranica za plaćanje nije se mogla otvoriti. Pokušajte ponovo.'; });
+1 -1
View File
@@ -795,7 +795,7 @@
fetch(KAUFEN_ENDPUNKT, {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ priceId: priceId }),
body: JSON.stringify({ priceId: priceId, sprache: zielsprache() }),
})
.then(function (r) { return r.json(); })
.then(function (d) {
+1 -1
View File
@@ -407,7 +407,7 @@
if (!konsens.checked) { fehler.style.display = 'block'; fehler.textContent = 'Τσεκάρετε πρώτα το πλαίσιο.'; konsens.focus(); return; }
fehler.style.display = 'none';
var alt = knopf.innerHTML; knopf.disabled = true;
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId }) })
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId, sprache: 'el' }) })
.then(function (r) { return r.json(); })
.then(function (d) { if (d && d.url) { window.location.href = d.url; return; } throw new Error('x'); })
.catch(function () { knopf.disabled = false; knopf.innerHTML = alt; fehler.style.display = 'block'; fehler.textContent = 'Η σελίδα πληρωμής δεν άνοιξε. Δοκιμάστε ξανά.'; });
+1 -1
View File
@@ -407,7 +407,7 @@
if (!konsens.checked) { fehler.style.display = 'block'; fehler.textContent = 'Please tick the box first.'; konsens.focus(); return; }
fehler.style.display = 'none';
var alt = knopf.innerHTML; knopf.disabled = true;
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId }) })
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId, sprache: 'en' }) })
.then(function (r) { return r.json(); })
.then(function (d) { if (d && d.url) { window.location.href = d.url; return; } throw new Error('x'); })
.catch(function () { knopf.disabled = false; knopf.innerHTML = alt; fehler.style.display = 'block'; fehler.textContent = 'The payment page could not be opened. Please try again.'; });
+1 -1
View File
@@ -407,7 +407,7 @@
if (!konsens.checked) { fehler.style.display = 'block'; fehler.textContent = 'Marca primero la casilla.'; konsens.focus(); return; }
fehler.style.display = 'none';
var alt = knopf.innerHTML; knopf.disabled = true;
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId }) })
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId, sprache: 'es' }) })
.then(function (r) { return r.json(); })
.then(function (d) { if (d && d.url) { window.location.href = d.url; return; } throw new Error('x'); })
.catch(function () { knopf.disabled = false; knopf.innerHTML = alt; fehler.style.display = 'block'; fehler.textContent = 'No se pudo abrir la página de pago. Inténtalo de nuevo.'; });
+1 -1
View File
@@ -407,7 +407,7 @@
if (!konsens.checked) { fehler.style.display = 'block'; fehler.textContent = 'لطفاً ابتدا تیک را بزنید.'; konsens.focus(); return; }
fehler.style.display = 'none';
var alt = knopf.innerHTML; knopf.disabled = true;
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId }) })
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId, sprache: 'fa' }) })
.then(function (r) { return r.json(); })
.then(function (d) { if (d && d.url) { window.location.href = d.url; return; } throw new Error('x'); })
.catch(function () { knopf.disabled = false; knopf.innerHTML = alt; fehler.style.display = 'block'; fehler.textContent = 'صفحه پرداخت باز نشد. لطفاً دوباره تلاش کنید.'; });
+1 -1
View File
@@ -407,7 +407,7 @@
if (!konsens.checked) { fehler.style.display = 'block'; fehler.textContent = 'Veuillez d’abord cocher la case.'; konsens.focus(); return; }
fehler.style.display = 'none';
var alt = knopf.innerHTML; knopf.disabled = true;
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId }) })
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId, sprache: 'fr' }) })
.then(function (r) { return r.json(); })
.then(function (d) { if (d && d.url) { window.location.href = d.url; return; } throw new Error('x'); })
.catch(function () { knopf.disabled = false; knopf.innerHTML = alt; fehler.style.display = 'block'; fehler.textContent = 'La page de paiement n’a pas pu être ouverte. Réessayez.'; });
+1 -1
View File
@@ -407,7 +407,7 @@
if (!konsens.checked) { fehler.style.display = 'block'; fehler.textContent = 'कृपया पहले बॉक्स पर निशान लगाएँ।'; konsens.focus(); return; }
fehler.style.display = 'none';
var alt = knopf.innerHTML; knopf.disabled = true;
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId }) })
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId, sprache: 'hi' }) })
.then(function (r) { return r.json(); })
.then(function (d) { if (d && d.url) { window.location.href = d.url; return; } throw new Error('x'); })
.catch(function () { knopf.disabled = false; knopf.innerHTML = alt; fehler.style.display = 'block'; fehler.textContent = 'भुगतान पृष्ठ नहीं खुल सका। कृपया फिर कोशिश करें।'; });
+1 -1
View File
@@ -407,7 +407,7 @@
if (!konsens.checked) { fehler.style.display = 'block'; fehler.textContent = 'Molimo najprije označite kućicu.'; konsens.focus(); return; }
fehler.style.display = 'none';
var alt = knopf.innerHTML; knopf.disabled = true;
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId }) })
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId, sprache: 'hr' }) })
.then(function (r) { return r.json(); })
.then(function (d) { if (d && d.url) { window.location.href = d.url; return; } throw new Error('x'); })
.catch(function () { knopf.disabled = false; knopf.innerHTML = alt; fehler.style.display = 'block'; fehler.textContent = 'Stranica za plaćanje nije se mogla otvoriti. Pokušajte ponovno.'; });
+1 -1
View File
@@ -407,7 +407,7 @@
if (!konsens.checked) { fehler.style.display = 'block'; fehler.textContent = 'Kérjük, előbb jelölje be a négyzetet.'; konsens.focus(); return; }
fehler.style.display = 'none';
var alt = knopf.innerHTML; knopf.disabled = true;
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId }) })
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId, sprache: 'hu' }) })
.then(function (r) { return r.json(); })
.then(function (d) { if (d && d.url) { window.location.href = d.url; return; } throw new Error('x'); })
.catch(function () { knopf.disabled = false; knopf.innerHTML = alt; fehler.style.display = 'block'; fehler.textContent = 'A fizetési oldal nem nyílt meg. Próbálja újra.'; });
+1 -1
View File
@@ -735,7 +735,7 @@
fetch(BASIS + '/kaufen', {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ priceId: priceId }),
body: JSON.stringify({ priceId: priceId, sprache: 'de' }),
})
.then(function (r) { return r.json(); })
.then(function (d) { if (d && d.url) { window.location.href = d.url; return; } throw new Error('keine url'); })
+1 -1
View File
@@ -407,7 +407,7 @@
if (!konsens.checked) { fehler.style.display = 'block'; fehler.textContent = 'Spunta prima la casella.'; konsens.focus(); return; }
fehler.style.display = 'none';
var alt = knopf.innerHTML; knopf.disabled = true;
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId }) })
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId, sprache: 'it' }) })
.then(function (r) { return r.json(); })
.then(function (d) { if (d && d.url) { window.location.href = d.url; return; } throw new Error('x'); })
.catch(function () { knopf.disabled = false; knopf.innerHTML = alt; fehler.style.display = 'block'; fehler.textContent = 'Non è stato possibile aprire la pagina di pagamento. Riprova.'; });
+1 -1
View File
@@ -407,7 +407,7 @@
if (!konsens.checked) { fehler.style.display = 'block'; fehler.textContent = 'Ji kerema xwe pêşî qutîkê nîşan bike.'; konsens.focus(); return; }
fehler.style.display = 'none';
var alt = knopf.innerHTML; knopf.disabled = true;
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId }) })
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId, sprache: 'ku' }) })
.then(function (r) { return r.json(); })
.then(function (d) { if (d && d.url) { window.location.href = d.url; return; } throw new Error('x'); })
.catch(function () { knopf.disabled = false; knopf.innerHTML = alt; fehler.style.display = 'block'; fehler.textContent = 'Rûpela dravdanê venebû. Ji kerema xwe dîsa biceribîne.'; });
+1 -1
View File
@@ -407,7 +407,7 @@
if (!konsens.checked) { fehler.style.display = 'block'; fehler.textContent = 'Najpierw zaznacz pole.'; konsens.focus(); return; }
fehler.style.display = 'none';
var alt = knopf.innerHTML; knopf.disabled = true;
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId }) })
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId, sprache: 'pl' }) })
.then(function (r) { return r.json(); })
.then(function (d) { if (d && d.url) { window.location.href = d.url; return; } throw new Error('x'); })
.catch(function () { knopf.disabled = false; knopf.innerHTML = alt; fehler.style.display = 'block'; fehler.textContent = 'Nie udało się otworzyć strony płatności. Spróbuj ponownie.'; });
+1 -1
View File
@@ -407,7 +407,7 @@
if (!konsens.checked) { fehler.style.display = 'block'; fehler.textContent = 'مهرباني وکړئ لومړی بکس نښه کړئ.'; konsens.focus(); return; }
fehler.style.display = 'none';
var alt = knopf.innerHTML; knopf.disabled = true;
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId }) })
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId, sprache: 'ps' }) })
.then(function (r) { return r.json(); })
.then(function (d) { if (d && d.url) { window.location.href = d.url; return; } throw new Error('x'); })
.catch(function () { knopf.disabled = false; knopf.innerHTML = alt; fehler.style.display = 'block'; fehler.textContent = 'د تادیې پاڼه نه پرانیستل کېده. مهرباني وکړئ بیا هڅه وکړئ.'; });
+1 -1
View File
@@ -407,7 +407,7 @@
if (!konsens.checked) { fehler.style.display = 'block'; fehler.textContent = 'Assinale primeiro a caixa.'; konsens.focus(); return; }
fehler.style.display = 'none';
var alt = knopf.innerHTML; knopf.disabled = true;
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId }) })
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId, sprache: 'pt' }) })
.then(function (r) { return r.json(); })
.then(function (d) { if (d && d.url) { window.location.href = d.url; return; } throw new Error('x'); })
.catch(function () { knopf.disabled = false; knopf.innerHTML = alt; fehler.style.display = 'block'; fehler.textContent = 'Não foi possível abrir a página de pagamento. Tente novamente.'; });
+1 -1
View File
@@ -407,7 +407,7 @@
if (!konsens.checked) { fehler.style.display = 'block'; fehler.textContent = 'Te rugăm să bifezi mai întâi căsuța.'; konsens.focus(); return; }
fehler.style.display = 'none';
var alt = knopf.innerHTML; knopf.disabled = true;
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId }) })
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId, sprache: 'ro' }) })
.then(function (r) { return r.json(); })
.then(function (d) { if (d && d.url) { window.location.href = d.url; return; } throw new Error('x'); })
.catch(function () { knopf.disabled = false; knopf.innerHTML = alt; fehler.style.display = 'block'; fehler.textContent = 'Pagina de plată nu a putut fi deschisă. Încearcă din nou.'; });
+1 -1
View File
@@ -407,7 +407,7 @@
if (!konsens.checked) { fehler.style.display = 'block'; fehler.textContent = 'Пожалуйста, сначала отметьте галочку.'; konsens.focus(); return; }
fehler.style.display = 'none';
var alt = knopf.innerHTML; knopf.disabled = true;
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId }) })
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId, sprache: 'ru' }) })
.then(function (r) { return r.json(); })
.then(function (d) { if (d && d.url) { window.location.href = d.url; return; } throw new Error('x'); })
.catch(function () { knopf.disabled = false; knopf.innerHTML = alt; fehler.style.display = 'block'; fehler.textContent = 'Страницу оплаты не удалось открыть. Попробуйте ещё раз.'; });
+28 -28
View File
@@ -3,7 +3,7 @@
xmlns:xhtml="http://www.w3.org/1999/xhtml">
<url>
<loc>https://behoerdenklar.de/</loc>
<lastmod>2026-09-19</lastmod>
<lastmod>2026-09-23</lastmod>
<xhtml:link rel="alternate" hreflang="de" href="https://behoerdenklar.de/"/>
<xhtml:link rel="alternate" hreflang="tr" href="https://behoerdenklar.de/tr"/>
<xhtml:link rel="alternate" hreflang="ar" href="https://behoerdenklar.de/ar"/>
@@ -36,7 +36,7 @@
</url>
<url>
<loc>https://behoerdenklar.de/tr</loc>
<lastmod>2026-09-19</lastmod>
<lastmod>2026-09-23</lastmod>
<xhtml:link rel="alternate" hreflang="de" href="https://behoerdenklar.de/"/>
<xhtml:link rel="alternate" hreflang="tr" href="https://behoerdenklar.de/tr"/>
<xhtml:link rel="alternate" hreflang="ar" href="https://behoerdenklar.de/ar"/>
@@ -69,7 +69,7 @@
</url>
<url>
<loc>https://behoerdenklar.de/ar</loc>
<lastmod>2026-09-19</lastmod>
<lastmod>2026-09-23</lastmod>
<xhtml:link rel="alternate" hreflang="de" href="https://behoerdenklar.de/"/>
<xhtml:link rel="alternate" hreflang="tr" href="https://behoerdenklar.de/tr"/>
<xhtml:link rel="alternate" hreflang="ar" href="https://behoerdenklar.de/ar"/>
@@ -102,7 +102,7 @@
</url>
<url>
<loc>https://behoerdenklar.de/ru</loc>
<lastmod>2026-09-19</lastmod>
<lastmod>2026-09-23</lastmod>
<xhtml:link rel="alternate" hreflang="de" href="https://behoerdenklar.de/"/>
<xhtml:link rel="alternate" hreflang="tr" href="https://behoerdenklar.de/tr"/>
<xhtml:link rel="alternate" hreflang="ar" href="https://behoerdenklar.de/ar"/>
@@ -135,7 +135,7 @@
</url>
<url>
<loc>https://behoerdenklar.de/uk</loc>
<lastmod>2026-09-19</lastmod>
<lastmod>2026-09-23</lastmod>
<xhtml:link rel="alternate" hreflang="de" href="https://behoerdenklar.de/"/>
<xhtml:link rel="alternate" hreflang="tr" href="https://behoerdenklar.de/tr"/>
<xhtml:link rel="alternate" hreflang="ar" href="https://behoerdenklar.de/ar"/>
@@ -168,7 +168,7 @@
</url>
<url>
<loc>https://behoerdenklar.de/pl</loc>
<lastmod>2026-09-19</lastmod>
<lastmod>2026-09-23</lastmod>
<xhtml:link rel="alternate" hreflang="de" href="https://behoerdenklar.de/"/>
<xhtml:link rel="alternate" hreflang="tr" href="https://behoerdenklar.de/tr"/>
<xhtml:link rel="alternate" hreflang="ar" href="https://behoerdenklar.de/ar"/>
@@ -201,7 +201,7 @@
</url>
<url>
<loc>https://behoerdenklar.de/ro</loc>
<lastmod>2026-09-19</lastmod>
<lastmod>2026-09-23</lastmod>
<xhtml:link rel="alternate" hreflang="de" href="https://behoerdenklar.de/"/>
<xhtml:link rel="alternate" hreflang="tr" href="https://behoerdenklar.de/tr"/>
<xhtml:link rel="alternate" hreflang="ar" href="https://behoerdenklar.de/ar"/>
@@ -234,7 +234,7 @@
</url>
<url>
<loc>https://behoerdenklar.de/en</loc>
<lastmod>2026-09-19</lastmod>
<lastmod>2026-09-23</lastmod>
<xhtml:link rel="alternate" hreflang="de" href="https://behoerdenklar.de/"/>
<xhtml:link rel="alternate" hreflang="tr" href="https://behoerdenklar.de/tr"/>
<xhtml:link rel="alternate" hreflang="ar" href="https://behoerdenklar.de/ar"/>
@@ -267,7 +267,7 @@
</url>
<url>
<loc>https://behoerdenklar.de/fa</loc>
<lastmod>2026-09-19</lastmod>
<lastmod>2026-09-23</lastmod>
<xhtml:link rel="alternate" hreflang="de" href="https://behoerdenklar.de/"/>
<xhtml:link rel="alternate" hreflang="tr" href="https://behoerdenklar.de/tr"/>
<xhtml:link rel="alternate" hreflang="ar" href="https://behoerdenklar.de/ar"/>
@@ -300,7 +300,7 @@
</url>
<url>
<loc>https://behoerdenklar.de/ku</loc>
<lastmod>2026-09-19</lastmod>
<lastmod>2026-09-23</lastmod>
<xhtml:link rel="alternate" hreflang="de" href="https://behoerdenklar.de/"/>
<xhtml:link rel="alternate" hreflang="tr" href="https://behoerdenklar.de/tr"/>
<xhtml:link rel="alternate" hreflang="ar" href="https://behoerdenklar.de/ar"/>
@@ -333,7 +333,7 @@
</url>
<url>
<loc>https://behoerdenklar.de/bg</loc>
<lastmod>2026-09-19</lastmod>
<lastmod>2026-09-23</lastmod>
<xhtml:link rel="alternate" hreflang="de" href="https://behoerdenklar.de/"/>
<xhtml:link rel="alternate" hreflang="tr" href="https://behoerdenklar.de/tr"/>
<xhtml:link rel="alternate" hreflang="ar" href="https://behoerdenklar.de/ar"/>
@@ -366,7 +366,7 @@
</url>
<url>
<loc>https://behoerdenklar.de/hr</loc>
<lastmod>2026-09-19</lastmod>
<lastmod>2026-09-23</lastmod>
<xhtml:link rel="alternate" hreflang="de" href="https://behoerdenklar.de/"/>
<xhtml:link rel="alternate" hreflang="tr" href="https://behoerdenklar.de/tr"/>
<xhtml:link rel="alternate" hreflang="ar" href="https://behoerdenklar.de/ar"/>
@@ -399,7 +399,7 @@
</url>
<url>
<loc>https://behoerdenklar.de/sr</loc>
<lastmod>2026-09-19</lastmod>
<lastmod>2026-09-23</lastmod>
<xhtml:link rel="alternate" hreflang="de" href="https://behoerdenklar.de/"/>
<xhtml:link rel="alternate" hreflang="tr" href="https://behoerdenklar.de/tr"/>
<xhtml:link rel="alternate" hreflang="ar" href="https://behoerdenklar.de/ar"/>
@@ -432,7 +432,7 @@
</url>
<url>
<loc>https://behoerdenklar.de/bs</loc>
<lastmod>2026-09-19</lastmod>
<lastmod>2026-09-23</lastmod>
<xhtml:link rel="alternate" hreflang="de" href="https://behoerdenklar.de/"/>
<xhtml:link rel="alternate" hreflang="tr" href="https://behoerdenklar.de/tr"/>
<xhtml:link rel="alternate" hreflang="ar" href="https://behoerdenklar.de/ar"/>
@@ -465,7 +465,7 @@
</url>
<url>
<loc>https://behoerdenklar.de/sq</loc>
<lastmod>2026-09-19</lastmod>
<lastmod>2026-09-23</lastmod>
<xhtml:link rel="alternate" hreflang="de" href="https://behoerdenklar.de/"/>
<xhtml:link rel="alternate" hreflang="tr" href="https://behoerdenklar.de/tr"/>
<xhtml:link rel="alternate" hreflang="ar" href="https://behoerdenklar.de/ar"/>
@@ -498,7 +498,7 @@
</url>
<url>
<loc>https://behoerdenklar.de/it</loc>
<lastmod>2026-09-19</lastmod>
<lastmod>2026-09-23</lastmod>
<xhtml:link rel="alternate" hreflang="de" href="https://behoerdenklar.de/"/>
<xhtml:link rel="alternate" hreflang="tr" href="https://behoerdenklar.de/tr"/>
<xhtml:link rel="alternate" hreflang="ar" href="https://behoerdenklar.de/ar"/>
@@ -531,7 +531,7 @@
</url>
<url>
<loc>https://behoerdenklar.de/el</loc>
<lastmod>2026-09-19</lastmod>
<lastmod>2026-09-23</lastmod>
<xhtml:link rel="alternate" hreflang="de" href="https://behoerdenklar.de/"/>
<xhtml:link rel="alternate" hreflang="tr" href="https://behoerdenklar.de/tr"/>
<xhtml:link rel="alternate" hreflang="ar" href="https://behoerdenklar.de/ar"/>
@@ -564,7 +564,7 @@
</url>
<url>
<loc>https://behoerdenklar.de/es</loc>
<lastmod>2026-09-19</lastmod>
<lastmod>2026-09-23</lastmod>
<xhtml:link rel="alternate" hreflang="de" href="https://behoerdenklar.de/"/>
<xhtml:link rel="alternate" hreflang="tr" href="https://behoerdenklar.de/tr"/>
<xhtml:link rel="alternate" hreflang="ar" href="https://behoerdenklar.de/ar"/>
@@ -597,7 +597,7 @@
</url>
<url>
<loc>https://behoerdenklar.de/pt</loc>
<lastmod>2026-09-19</lastmod>
<lastmod>2026-09-23</lastmod>
<xhtml:link rel="alternate" hreflang="de" href="https://behoerdenklar.de/"/>
<xhtml:link rel="alternate" hreflang="tr" href="https://behoerdenklar.de/tr"/>
<xhtml:link rel="alternate" hreflang="ar" href="https://behoerdenklar.de/ar"/>
@@ -630,7 +630,7 @@
</url>
<url>
<loc>https://behoerdenklar.de/fr</loc>
<lastmod>2026-09-19</lastmod>
<lastmod>2026-09-23</lastmod>
<xhtml:link rel="alternate" hreflang="de" href="https://behoerdenklar.de/"/>
<xhtml:link rel="alternate" hreflang="tr" href="https://behoerdenklar.de/tr"/>
<xhtml:link rel="alternate" hreflang="ar" href="https://behoerdenklar.de/ar"/>
@@ -663,7 +663,7 @@
</url>
<url>
<loc>https://behoerdenklar.de/hu</loc>
<lastmod>2026-09-19</lastmod>
<lastmod>2026-09-23</lastmod>
<xhtml:link rel="alternate" hreflang="de" href="https://behoerdenklar.de/"/>
<xhtml:link rel="alternate" hreflang="tr" href="https://behoerdenklar.de/tr"/>
<xhtml:link rel="alternate" hreflang="ar" href="https://behoerdenklar.de/ar"/>
@@ -696,7 +696,7 @@
</url>
<url>
<loc>https://behoerdenklar.de/vi</loc>
<lastmod>2026-09-19</lastmod>
<lastmod>2026-09-23</lastmod>
<xhtml:link rel="alternate" hreflang="de" href="https://behoerdenklar.de/"/>
<xhtml:link rel="alternate" hreflang="tr" href="https://behoerdenklar.de/tr"/>
<xhtml:link rel="alternate" hreflang="ar" href="https://behoerdenklar.de/ar"/>
@@ -729,7 +729,7 @@
</url>
<url>
<loc>https://behoerdenklar.de/hi</loc>
<lastmod>2026-09-19</lastmod>
<lastmod>2026-09-23</lastmod>
<xhtml:link rel="alternate" hreflang="de" href="https://behoerdenklar.de/"/>
<xhtml:link rel="alternate" hreflang="tr" href="https://behoerdenklar.de/tr"/>
<xhtml:link rel="alternate" hreflang="ar" href="https://behoerdenklar.de/ar"/>
@@ -762,7 +762,7 @@
</url>
<url>
<loc>https://behoerdenklar.de/ur</loc>
<lastmod>2026-09-19</lastmod>
<lastmod>2026-09-23</lastmod>
<xhtml:link rel="alternate" hreflang="de" href="https://behoerdenklar.de/"/>
<xhtml:link rel="alternate" hreflang="tr" href="https://behoerdenklar.de/tr"/>
<xhtml:link rel="alternate" hreflang="ar" href="https://behoerdenklar.de/ar"/>
@@ -795,7 +795,7 @@
</url>
<url>
<loc>https://behoerdenklar.de/ps</loc>
<lastmod>2026-09-19</lastmod>
<lastmod>2026-09-23</lastmod>
<xhtml:link rel="alternate" hreflang="de" href="https://behoerdenklar.de/"/>
<xhtml:link rel="alternate" hreflang="tr" href="https://behoerdenklar.de/tr"/>
<xhtml:link rel="alternate" hreflang="ar" href="https://behoerdenklar.de/ar"/>
@@ -828,7 +828,7 @@
</url>
<url>
<loc>https://behoerdenklar.de/ti</loc>
<lastmod>2026-09-19</lastmod>
<lastmod>2026-09-23</lastmod>
<xhtml:link rel="alternate" hreflang="de" href="https://behoerdenklar.de/"/>
<xhtml:link rel="alternate" hreflang="tr" href="https://behoerdenklar.de/tr"/>
<xhtml:link rel="alternate" hreflang="ar" href="https://behoerdenklar.de/ar"/>
@@ -861,7 +861,7 @@
</url>
<url>
<loc>https://behoerdenklar.de/so</loc>
<lastmod>2026-09-19</lastmod>
<lastmod>2026-09-23</lastmod>
<xhtml:link rel="alternate" hreflang="de" href="https://behoerdenklar.de/"/>
<xhtml:link rel="alternate" hreflang="tr" href="https://behoerdenklar.de/tr"/>
<xhtml:link rel="alternate" hreflang="ar" href="https://behoerdenklar.de/ar"/>
@@ -894,7 +894,7 @@
</url>
<url>
<loc>https://behoerdenklar.de/zh</loc>
<lastmod>2026-09-19</lastmod>
<lastmod>2026-09-23</lastmod>
<xhtml:link rel="alternate" hreflang="de" href="https://behoerdenklar.de/"/>
<xhtml:link rel="alternate" hreflang="tr" href="https://behoerdenklar.de/tr"/>
<xhtml:link rel="alternate" hreflang="ar" href="https://behoerdenklar.de/ar"/>
+1 -1
View File
@@ -407,7 +407,7 @@
if (!konsens.checked) { fehler.style.display = 'block'; fehler.textContent = 'Fadlan marka hore calaamadee sanduuqa.'; konsens.focus(); return; }
fehler.style.display = 'none';
var alt = knopf.innerHTML; knopf.disabled = true;
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId }) })
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId, sprache: 'so' }) })
.then(function (r) { return r.json(); })
.then(function (d) { if (d && d.url) { window.location.href = d.url; return; } throw new Error('x'); })
.catch(function () { knopf.disabled = false; knopf.innerHTML = alt; fehler.style.display = 'block'; fehler.textContent = 'Boggii lacag bixinta lama furi karin. Fadlan mar kale isku day.'; });
+1 -1
View File
@@ -407,7 +407,7 @@
if (!konsens.checked) { fehler.style.display = 'block'; fehler.textContent = 'Ju lutemi shënoni fillimisht kutinë.'; konsens.focus(); return; }
fehler.style.display = 'none';
var alt = knopf.innerHTML; knopf.disabled = true;
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId }) })
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId, sprache: 'sq' }) })
.then(function (r) { return r.json(); })
.then(function (d) { if (d && d.url) { window.location.href = d.url; return; } throw new Error('x'); })
.catch(function () { knopf.disabled = false; knopf.innerHTML = alt; fehler.style.display = 'block'; fehler.textContent = 'Faqja e pagesës nuk u hap. Ju lutemi provoni sërish.'; });
+1 -1
View File
@@ -407,7 +407,7 @@
if (!konsens.checked) { fehler.style.display = 'block'; fehler.textContent = 'Молимо најпре означите поље.'; konsens.focus(); return; }
fehler.style.display = 'none';
var alt = knopf.innerHTML; knopf.disabled = true;
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId }) })
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId, sprache: 'sr' }) })
.then(function (r) { return r.json(); })
.then(function (d) { if (d && d.url) { window.location.href = d.url; return; } throw new Error('x'); })
.catch(function () { knopf.disabled = false; knopf.innerHTML = alt; fehler.style.display = 'block'; fehler.textContent = 'Страница за плаћање није могла да се отвори. Покушајте поново.'; });
+1 -1
View File
@@ -407,7 +407,7 @@
if (!konsens.checked) { fehler.style.display = 'block'; fehler.textContent = 'በጃኻ ቅድሚ ኩሉ ነቲ ሳጹን ምልክት ግበረሉ።'; konsens.focus(); return; }
fehler.style.display = 'none';
var alt = knopf.innerHTML; knopf.disabled = true;
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId }) })
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId, sprache: 'ti' }) })
.then(function (r) { return r.json(); })
.then(function (d) { if (d && d.url) { window.location.href = d.url; return; } throw new Error('x'); })
.catch(function () { knopf.disabled = false; knopf.innerHTML = alt; fehler.style.display = 'block'; fehler.textContent = 'ናይ ክፍሊት ገጽ ክኽፈት ኣይከኣለን። በጃኻ እንደገና ፈትን።'; });
+1 -1
View File
@@ -407,7 +407,7 @@
if (!konsens.checked) { fehler.style.display = 'block'; fehler.textContent = 'Lütfen önce kutucuğu işaretleyin.'; konsens.focus(); return; }
fehler.style.display = 'none';
var alt = knopf.innerHTML; knopf.disabled = true;
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId }) })
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId, sprache: 'tr' }) })
.then(function (r) { return r.json(); })
.then(function (d) { if (d && d.url) { window.location.href = d.url; return; } throw new Error('x'); })
.catch(function () { knopf.disabled = false; knopf.innerHTML = alt; fehler.style.display = 'block'; fehler.textContent = 'Ödeme sayfası açılamadı. Lütfen tekrar deneyin.'; });
+1 -1
View File
@@ -407,7 +407,7 @@
if (!konsens.checked) { fehler.style.display = 'block'; fehler.textContent = 'Будь ласка, спершу поставте галочку.'; konsens.focus(); return; }
fehler.style.display = 'none';
var alt = knopf.innerHTML; knopf.disabled = true;
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId }) })
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId, sprache: 'uk' }) })
.then(function (r) { return r.json(); })
.then(function (d) { if (d && d.url) { window.location.href = d.url; return; } throw new Error('x'); })
.catch(function () { knopf.disabled = false; knopf.innerHTML = alt; fehler.style.display = 'block'; fehler.textContent = 'Не вдалося відкрити сторінку оплати. Спробуйте ще раз.'; });
+1 -1
View File
@@ -407,7 +407,7 @@
if (!konsens.checked) { fehler.style.display = 'block'; fehler.textContent = 'براہ کرم پہلے خانے پر نشان لگائیں۔'; konsens.focus(); return; }
fehler.style.display = 'none';
var alt = knopf.innerHTML; knopf.disabled = true;
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId }) })
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId, sprache: 'ur' }) })
.then(function (r) { return r.json(); })
.then(function (d) { if (d && d.url) { window.location.href = d.url; return; } throw new Error('x'); })
.catch(function () { knopf.disabled = false; knopf.innerHTML = alt; fehler.style.display = 'block'; fehler.textContent = 'ادائیگی کا صفحہ نہیں کھل سکا۔ براہ کرم دوبارہ کوشش کریں۔'; });
+1 -1
View File
@@ -407,7 +407,7 @@
if (!konsens.checked) { fehler.style.display = 'block'; fehler.textContent = 'Vui lòng đánh dấu ô trước.'; konsens.focus(); return; }
fehler.style.display = 'none';
var alt = knopf.innerHTML; knopf.disabled = true;
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId }) })
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId, sprache: 'vi' }) })
.then(function (r) { return r.json(); })
.then(function (d) { if (d && d.url) { window.location.href = d.url; return; } throw new Error('x'); })
.catch(function () { knopf.disabled = false; knopf.innerHTML = alt; fehler.style.display = 'block'; fehler.textContent = 'Không mở được trang thanh toán. Vui lòng thử lại.'; });
+1 -1
View File
@@ -407,7 +407,7 @@
if (!konsens.checked) { fehler.style.display = 'block'; fehler.textContent = '请先勾选方框。'; konsens.focus(); return; }
fehler.style.display = 'none';
var alt = knopf.innerHTML; knopf.disabled = true;
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId }) })
fetch(BASIS + '/kaufen', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ priceId: priceId, sprache: 'zh' }) })
.then(function (r) { return r.json(); })
.then(function (d) { if (d && d.url) { window.location.href = d.url; return; } throw new Error('x'); })
.catch(function () { knopf.disabled = false; knopf.innerHTML = alt; fehler.style.display = 'block'; fehler.textContent = '无法打开付款页面,请重试。'; });