diff --git a/server/routes/shop.js b/server/routes/shop.js index ff38433..bc5811f 100644 --- a/server/routes/shop.js +++ b/server/routes/shop.js @@ -57,6 +57,7 @@ const MELDUNG = { eingabe: 'Die Eingabe fehlt oder ist unlesbar.', stripeKundenansicht: 'In der Kundenansicht kann das Stripe-Konto nicht eingerichtet werden.', stripeFern: 'Stripe ist gerade nicht erreichbar. Bitte versuch es gleich noch einmal.', + plattform: 'Die Stripe-Anbindung ist bei WEBklar noch nicht fertig eingerichtet. Wir kümmern uns darum – schreib uns gern im Chat.', keinKonto: 'Es ist noch kein Stripe-Konto angelegt.', } @@ -484,11 +485,18 @@ const nurKundeStripe = (req, res, next) => { } /** Stripe-Aufruf: jeder Fehler von Stripe wird zu 502 mit festem Text (Stripe-Texte verlassen den Server nie, geloggt wird nur Typ und Code). */ +// Connect im WEBklar-Konto nicht fertig (Plattformprofil fehlt oder Connect nicht aktiviert): das kann nur WEBklar beheben +const PLATTFORM_FEHLT = /platform profile|signed up for Connect/i + async function ueberStripe(fn) { try { return await fn() } catch (err) { if (err?.status >= 400 && err.status < 500 && !err.type) throw err + if (err?.type === 'StripeInvalidRequestError' && PLATTFORM_FEHLT.test(String(err.message || ''))) { + console.error('[shop] Stripe Connect: Plattformprofil fehlt (Stripe-Dashboard → Connect → Fragebogen ausfüllen)') + throw stop(503, MELDUNG.plattform, 'plattform_nicht_bereit') + } console.error(`[shop] Stripe ${String(err?.type ?? err?.name ?? 'Fehler').slice(0, 60)} ${String(err?.code ?? '').slice(0, 60)}`.trim()) throw stop(502, MELDUNG.stripeFern) } diff --git a/test/shopStripeRoutes.test.js b/test/shopStripeRoutes.test.js index 0b10ecd..712cf92 100644 --- a/test/shopStripeRoutes.test.js +++ b/test/shopStripeRoutes.test.js @@ -188,6 +188,29 @@ test('Stripe-Fehler: 502 mit festem Du-Text, nie der Stripe-Text; bei gescheiter assert.equal(log.some((l) => l.includes('Geheim') || l.includes('sk_live')), false) }) +test('Plattformprofil fehlt (Connect nicht fertig): 503 mit eigenem Du-Text und Code, fester Logeintrag ohne Stripe-Text', async () => { + const feature = await aktiviere() + const log = [] + const orig = console.error + console.error = (...a) => log.push(a.join(' ')) + try { + for (const message of [ + 'You must complete your platform profile to use Connect and create live connected accounts. Visit your dashboard at https://dashboard.stripe.com/connect/accounts/overview to answer the questionnaire.', + "You can only create new accounts if you've signed up for Connect, which you can learn how to do at https://stripe.com/docs/connect.", + ]) { + st.failNext({ method: 'POST', path: '/v1/accounts', status: 400, message }) + const a = await post('einrichten') + assert.deepEqual([a.status, a.body.code, a.body.error], [503, 'plattform_nicht_bereit', 'Die Stripe-Anbindung ist bei WEBklar noch nicht fertig eingerichtet. Wir kümmern uns darum – schreib uns gern im Chat.']) + assert.equal(JSON.stringify(a.body).includes('dashboard.stripe.com'), false) + } + assert.equal(shopConfigDoc(feature).stripeAccountId || '', '') + } finally { + console.error = orig + } + assert.equal(log.filter((l) => l.includes('Plattformprofil')).length, 2) + assert.equal(log.some((l) => l.includes('questionnaire') || l.includes('stripe.com')), false) +}) + test('Kundenansicht: der Wächter sperrt die Routen (nicht auf der Erlaubnisliste), der Router selbst auch ohne Wächter (Kundenansicht und Ansehen als)', async () => { const feature = await aktiviere() for (const pfad of ['einrichten', 'link', 'aktualisieren']) {