Refund status tracked separately from order status
Why it matters
When refund state is encoded only as order.status = 'refunded', the system cannot represent intermediate states: a refund that was requested but not yet processed, a refund that the payment provider rejected, or an order that was cancelled without a refund being issued at all (e.g., store credit was given instead). This is an iso-25010:2011 functional correctness failure and a GDPR Art. 17 (right to erasure / financial correction) accountability gap. Separate refund tracking also enables storing the provider's refund ID — essential for reconciling Stripe refunds against your own records and for debugging partial or failed refunds.
Severity rationale
High because a single 'refunded' status value cannot distinguish between pending, processing, completed, or failed refund states, making financial reconciliation and dispute resolution unreliable.
Remediation
Create a separate Refund model in prisma/schema.prisma with its own independent status lifecycle, and initiate refunds through a dedicated function in lib/refunds/create.ts.
// prisma/schema.prisma:
// model Refund {
// id String @id @default(cuid())
// orderId String
// amount Int // cents
// status String // pending | processing | completed | failed
// providerRefundId String?
// reason String?
// initiatedBy String?
// createdAt DateTime @default(now())
// updatedAt DateTime @updatedAt
// order Order @relation(fields: [orderId], references: [id])
// }
export async function initiateRefund(orderId: string, amount: number, reason: string, actorId: string) {
return db.refund.create({
data: { orderId, amount, status: 'pending', reason, initiatedBy: actorId },
})
}
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 Order Management Audit. The pattern definition, severity rationale, and remediation remain openly licensed under CC-BY-4.0.
External references
- iso-25010:2011 · functional-correctness — Functional Correctness
- gdpr · Art. 17 — Right to erasure / refund processing obligation
Taxons
History
- 2026-04-18·v1.0.0·Initial import from ecommerce-order-management·automated