Buchungskalender: Abschluss – Kleinigkeiten Server (Betrag/Waehrung, Erstattungs-Webhook, Obergrenze, Zaehler, Cache, Kommentare, Setup-Check)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
6d35674c1e
commit
1d9515823c
13 files changed
+123
-14
No files matched your search
@@ -223,7 +223,7 @@ test('Webhook: unbezahlt, fremdes Konto, unbekannte Anfrage ohne Wirkung; async_
|
||||
const { id, token } = await freigegeben()
|
||||
await post(url(id, token), { rechnungsadresse: ADRESSE, zahlart: 'online' })
|
||||
const sid = (await sp.ladeAnfrage(id)).stripeSessionId
|
||||
const unbezahlt = { ...st.completeSession(ACCOUNT, sid, { payment_status: 'unpaid', payment_intent: 'pi_2' }) }
|
||||
const unbezahlt = { ...st.completeSession(ACCOUNT, sid, { payment_status: 'unpaid', amount_total: 20000, payment_intent: 'pi_2' }) }
|
||||
await W.verarbeiteUkEreignis({ type: 'checkout.session.completed', account: ACCOUNT, data: { object: unbezahlt } }, NOW)
|
||||
assert.equal((await sp.ladeAnfrage(id)).status, 'gebucht')
|
||||
const bezahlt = { ...unbezahlt, payment_status: 'paid' }
|
||||
@@ -257,7 +257,7 @@ test('POST zahlung: neue Sitzung fuer gebuchte Online-Zahlung; vor Ort oder beza
|
||||
assert.match(r.body.url, /^https:\/\/checkout\.stripe\.test\//)
|
||||
assert.equal((await post(url(id, 'falsch', '/zahlung'), {})).status, 404)
|
||||
const sid = (await sp.ladeAnfrage(id)).stripeSessionId
|
||||
st.completeSession(ACCOUNT, sid, { payment_status: 'paid', payment_intent: 'pi_4' })
|
||||
st.completeSession(ACCOUNT, sid, { payment_status: 'paid', amount_total: 20000, payment_intent: 'pi_4' })
|
||||
const nach = await post(url(id, token, '/zahlung'), {})
|
||||
assert.equal(nach.status, 409)
|
||||
assert.equal((await sp.ladeAnfrage(id)).status, 'bezahlt')
|
||||
@@ -329,6 +329,42 @@ test('Erstattung: Stripe ging durch, Speichern scheiterte, KEIN Webhook -> Wiede
|
||||
assert.equal(erstattungen('pi_h2').reduce((s, x) => s + x.amount, 0), 20000)
|
||||
})
|
||||
|
||||
test('Zahlung mit falschem Betrag oder falscher Waehrung gilt nicht als Bezahlung: Warnung, automatisch voll erstattet, Buchung bleibt gebucht (Webhook und Abgleich)', async (t) => {
|
||||
t.mock.method(console, 'warn', () => {})
|
||||
const f1 = await freigegeben('2026-11-10', '2026-11-12')
|
||||
await post(url(f1.id, f1.token), { rechnungsadresse: ADRESSE, zahlart: 'online' })
|
||||
const sid1 = (await sp.ladeAnfrage(f1.id)).stripeSessionId
|
||||
st.setPaymentIntent(ACCOUNT, 'pi_falsch', { amount: 100 })
|
||||
const zuWenig = st.completeSession(ACCOUNT, sid1, { payment_status: 'paid', amount_total: 100, payment_intent: 'pi_falsch' })
|
||||
await W.verarbeiteUkEreignis({ type: 'checkout.session.completed', account: ACCOUNT, data: { object: zuWenig } }, NOW)
|
||||
assert.equal((await sp.ladeAnfrage(f1.id)).status, 'gebucht')
|
||||
assert.equal(erstattungen('pi_falsch').length, 1)
|
||||
assert.equal(erstattungen('pi_falsch')[0].amount, 100)
|
||||
// andere Waehrung
|
||||
const f2 = await freigegeben('2026-12-10', '2026-12-12')
|
||||
await post(url(f2.id, f2.token), { rechnungsadresse: ADRESSE, zahlart: 'online' })
|
||||
const sid2 = (await sp.ladeAnfrage(f2.id)).stripeSessionId
|
||||
st.setPaymentIntent(ACCOUNT, 'pi_usd', { amount: 20000 })
|
||||
const usd = { ...st.completeSession(ACCOUNT, sid2, { payment_status: 'paid', amount_total: 20000, payment_intent: 'pi_usd' }), currency: 'usd' }
|
||||
await W.verarbeiteUkEreignis({ type: 'checkout.session.completed', account: ACCOUNT, data: { object: usd } }, NOW)
|
||||
assert.equal((await sp.ladeAnfrage(f2.id)).status, 'gebucht')
|
||||
assert.equal(erstattungen('pi_usd').length, 1)
|
||||
})
|
||||
|
||||
test('Webhook charge.refunded: ohne gespeicherte Zahlung der Buchung oder mit fremder Zahlung keine Wirkung', async () => {
|
||||
const { id, ctx } = await bezahlt('pi_r1')
|
||||
await ab.storniere(ctx, id, { now: NOW })
|
||||
const charge = (pi, betrag) => ({ type: 'charge.refunded', account: ACCOUNT, data: { object: { id: 'ch_r', payment_intent: pi, amount_refunded: betrag, metadata: { wkUk: '1', webklar: 'unterkunft', anfrageId: id } } } })
|
||||
await W.verarbeiteUkEreignis(charge('pi_fremd', 5000), NOW)
|
||||
assert.equal((await sp.ladeAnfrage(id)).erstattetCent ?? 0, 0)
|
||||
await sp.aktualisiereAnfrage(id, { stripePaymentIntentId: '' })
|
||||
await W.verarbeiteUkEreignis(charge('pi_r1', 5000), NOW)
|
||||
assert.equal((await sp.ladeAnfrage(id)).erstattetCent ?? 0, 0, 'Buchung ohne gespeicherte Zahlung')
|
||||
await sp.aktualisiereAnfrage(id, { stripePaymentIntentId: 'pi_r1' })
|
||||
await W.verarbeiteUkEreignis(charge('pi_r1', 5000), NOW)
|
||||
assert.equal((await sp.ladeAnfrage(id)).erstattetCent, 5000)
|
||||
})
|
||||
|
||||
test('Webhook charge.refunded: erstattetCent = Maximum, nie zurueck', async () => {
|
||||
const { id, ctx } = await bezahlt('pi_8')
|
||||
await ab.storniere(ctx, id, { now: NOW })
|
||||
|
||||
Reference in new issue
Block a user