Refund logic exists
Why it matters
A cancellation handler that updates the booking status in the database but never calls the payment provider's refund API silently keeps customer money. Customers who cancel within the refund window see a "Cancelled" status but receive no refund — the money transfer is one-way. CWE-841 (behavioral workflow violation) applies: the business workflow specifies refund-on-cancel, but the code path that executes cancellation does not include the corresponding refund step. Customers discover the missing refund days later via their bank statement, producing chargebacks that are more expensive than the original refund would have been.
Severity rationale
Medium because the defect silently retains customer funds on cancellation, which is both a trust violation and a chargeback risk, though it requires cancellation of a paid booking to manifest.
Remediation
Trigger the refund API call inside the cancellation handler before updating the booking status. Implement this in src/lib/booking-service.ts or src/app/api/bookings/[id]/cancel/route.ts.
export async function cancelBooking(bookingId: string) {
const booking = await db.booking.findUniqueOrThrow({ where: { id: bookingId } });
if (booking.paymentIntentId && booking.status === 'CONFIRMED') {
await stripe.refunds.create({
payment_intent: booking.paymentIntentId,
reason: 'requested_by_customer',
});
}
await db.booking.update({
where: { id: bookingId },
data: { status: 'CANCELLED', cancelledAt: new Date() }
});
}
DetectionPro
The detection method for this pattern is part of AuditBuffet Pro.
The full method (what to look for, pass and fail conditions, and how results get reported) ships inside the Booking Flow & Lifecycle Audit. The pattern definition, severity rationale, and remediation remain openly licensed under CC-BY-4.0.
External references
- cwe · CWE-841 — Improper Enforcement of Behavioral Workflow
- iso-25010:2011 · functional-suitability.functional-correctness
Taxons
History
- 2026-04-18·v1.0.0·Initial import from booking-flow-lifecycle·automated